Implement Grand Chess
[capablanca.git] / lasker-2.2.3 / src / movecheck.c
index 468a8a3..30405fa 100644 (file)
@@ -1532,11 +1532,19 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   } else
   if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) && 
        !gs->palace && // [HGM] XQ: no promotions in xiangqi\r
-      ((mt->toRank == 0) || (mt->toRank == gs->ranks-1))) {
+      ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
+    int stm = colorval(gs->board[mt->fromFile][mt->fromRank]);
+    if(!promote && (mt->toRank == 0 || mt->toRank == gs->ranks-1)) { // promotion obligatory, but not specified
+       if(gs->promoType != 2) promote = QUEEN; else { // choose a default
+           for(promote=KING-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
+           if(promote == PAWN) return MOVE_ILLEGAL; // nothing available
+       }
+    } // if not obligatory, we defer unless promoton was explicitly specified!
     if(!gs->pawnDblStep && promote == PRINCESS) promote = MAN2;
     if(!gs->pawnDblStep && promote != FERZ2 && promote != MAN2) promote = FERZ; // [HGM] kludge to recognize shatranj
-    mt->piecePromotionTo = promote |\r
-      (colorval(gs->board[mt->fromFile][mt->fromRank]));\r
+    // 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
   } else {\r
     mt->piecePromotionTo = NOPIECE;\r
   }\r
@@ -1569,7 +1577,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
 \r
   sprintf(mt->algString, alg_unparse(gs, mt));\r
   fakeMove = *gs;\r
-  /* Calculates enPassant also */\r
+  /* Calculates enPassant also */
   execute_move(&fakeMove, mt, 0);\r
 \r
   /* Does making this move leave ME in check? */\r
@@ -1585,6 +1593,7 @@ int legal_andcheck_move(struct game_state_t * gs,
                        int tFile, int tRank)
 {
   struct move_t mt;
+
   if (!legal_move(gs, fFile, fRank, tFile, tRank))
     return 0;
   mt.color = gs->onMove;
@@ -1593,7 +1602,7 @@ int legal_andcheck_move(struct game_state_t * gs,
   mt.toFile = tFile;
   mt.toRank = tRank;
   /* This should take into account a pawn promoting to another piece */
-  if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
+  if (move_calculate(gs, &mt, NOPIECE) == MOVE_OK) 
     return 1;
   else
     return 0;
@@ -1871,7 +1880,6 @@ int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int pro
 \r
   if (mt->piecePromotionTo != NOPIECE) {
          promote = piecetype(mt->piecePromotionTo);\r
-printf("promotion piece = %d, type = %d",mt->piecePromotionTo, promote);\r
   }\r
 \r
   return move_calculate(gs, mt, promote);\r
@@ -1944,7 +1952,7 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
   for (i = 0; i < gs->files; i++) {\r
     gs->ep_possible[0][i] = 0;\r
     gs->ep_possible[1][i] = 0;\r
-  }\r
+  }
 /* Added by Sparky 3/16/95
 
    From soso@Viktoria.drp.fmph.uniba.sk Thu Mar 16 13:08:51 1995
@@ -2058,7 +2066,8 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
         return MOVE_NOMATERIAL;\r
   } else {\r
     gs->onMove = CToggle(gs->onMove);\r
-  }\r
+  }
+\r
   return MOVE_OK;\r
 }