Check validity of promotion piece in long algebraic
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 3 Jan 2012 22:07:11 +0000 (23:07 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 3 Jan 2012 22:07:11 +0000 (23:07 +0100)
Long algebraic moves have their own parser, and this was not yet checking
if the chosen promotion piece was valid, so that it was possible to
promote to Archbishop in normal Chess, etc.

lasker-2.2.3/src/movecheck.c

index a2cb8c9..6d05050 100644 (file)
@@ -1665,6 +1665,28 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
     // non-promotion can still be an option for deeper promotion zones
     mt->piecePromotionTo = promote ? (promote | stm) : NOPIECE;
     if(promote && gs->promoType == 2 && !gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
+    if(promote == KNIGHT && gs->royalKnight) return MOVE_ILLEGAL; // Knight not allowed in Knightmate
+    if(gs->promoType != 2 && promote > QUEEN) { // for promoType != 2 we must check explicitly if the requested pieceis compatible with the variant
+       switch(promote) {
+         case HAWK:
+         case SELEPHANT:
+           if(gs->drops != 2) return MOVE_ILLEGAL; // allowed only in S-Chess
+           break;
+         case MARSHALL:
+         case CARDINAL:
+           if(!gs->capablancaPieces) return MOVE_ILLEGAL; // allowed when flagged so
+           break;
+         case FERZ:
+         case FERZ2:
+           if(!gs->pawnDblStep) return MOVE_ILLEGAL; // allowed in Shatranj and Courier
+           break;
+         case MAN2:
+           if(!gs->royalKnight) return MOVE_ILLEGAL; // allowed only in Knightmate
+           break;
+         default:
+           return MOVE_ILLEGAL;
+       }
+    }
   } else
   if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) && 
       ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {