Debug Seirawan Chess
[capablanca.git] / lasker-2.2.3 / src / movecheck.c
index 6996d09..edeeea7 100644 (file)
@@ -1486,7 +1486,7 @@ int legal_move(struct game_state_t * gs,
 static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote)
 {
   struct game_state_t fakeMove;
-  int gating = 0;
+  int gating = 0, stm;
 
   mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
   mt->enPassant = 0;           /* Don't know yet, let execute move take care
@@ -1500,7 +1500,10 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   } else if(mt->fromFile == ALG_CASTLE) { 
        // [HGM] castle: generalized castling, fr and tr give from and to file of Rook.
            sprintf(mt->moveString, mt->toRank > mt->toFile ? "o-o-o" : "o-o");
+       if(gs->drops == 2 && promote && gs->holding[gs->onMove == BLACK][promote-1])
+           mt->piecePromotionTo = promote, gating = 1;
   } else {
+  stm = colorval(gs->board[mt->fromFile][mt->fromRank]);
   if(gs->promoType == 3) { // Shogi-style promotions: not just Pawns, but many pieces can promote
     int piece = gs->board[mt->fromFile][mt->fromRank];
     mt->piecePromotionTo = NOPIECE;
@@ -1536,7 +1539,6 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) && 
        !gs->palace && // [HGM] XQ: no promotions in xiangqi
       ((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=PIECES-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
@@ -1552,10 +1554,12 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
     int i; struct game *g = &game_globals.garray[gs->gameNum];
     if(!gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
     // now we must test virginity of the moved piece. Yegh!
-    for (i = g->numHalfMoves-2; i > 0; i -= 2) {
-      if (g->moveList[i].toFile == mt->fromFile && g->moveList[i].toRank == mt->fromRank) return MOVE_ILLEGAL;
+    for (i = g->numHalfMoves-1; i >= 0; i--) {
+      if (g->moveList[i].fromFile == mt->fromFile && g->moveList[i].fromRank == mt->fromRank ||
+          g->moveList[i].toFile   == mt->fromFile && g->moveList[i].toRank   == mt->fromRank) return MOVE_ILLEGAL;
     }
-    gating = 1; // gating OK; remember we did it for check test
+    mt->piecePromotionTo = promote; // gating OK
+    gating = 1; // remember we did it for check test
   } else {
     mt->piecePromotionTo = NOPIECE;
   }
@@ -1590,7 +1594,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom
   fakeMove = *gs;
   /* Calculates enPassant also */
   execute_move(&fakeMove, mt, 0);
-  if(gating) fakeMove.board[mt-fromFile][mt->fromRank] = NOPIECE; // [HGM] gating is only legal if non-gating move was (weird, but true)
+  if(gating) fakeMove.board[mt->fromFile][mt->fromRank] = NOPIECE; // [HGM] gating is only legal if non-gating move was (weird, but true)
 
   /* Does making this move leave ME in check? */
   if (in_check(&fakeMove))
@@ -1894,7 +1898,11 @@ int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int pro
 
   if (mt->piecePromotionTo != NOPIECE) {
          promote = piecetype(mt->piecePromotionTo);
-  } else if(gs->promoType == 3 && promote == MASTODON) promote = GOLD;
+  } else if (promote != NOPIECE) { // [HGM] promotion on long algebraic move; correct ambiguous types for variant
+    if(gs->promoType == 3 && promote == MASTODON) promote = GOLD;
+    if(gs->drops == 2 && promote == EMPRESS) promote = SELEPHANT;
+    if(gs->drops == 2 && promote == DRAGONHORSE) promote = HAWK;
+  }
 
   return move_calculate(gs, mt, promote);
 }
@@ -1933,10 +1941,14 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st
     gs->board[fKing][backRank] = NOPIECE;
     gs->board[mt->toRank][backRank] = rook;      // then put back
     gs->board[mt->toFile][backRank] = king;
+    if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE) { // [HGM] Seirawan-style gating
+      gs->board[fKing][backRank] = mt->piecePromotionTo | gs->onMove;   // for now always on King square
+      gs->holding[gs->onMove==WHITE ? 0 : 1][mt->piecePromotionTo-1]--; // remove gated piece from holdings
+    }
   } else {
   movedPiece = gs->board[mt->fromFile][mt->fromRank];
   tookPiece = gs->board[mt->toFile][mt->toRank];
-  if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE && pieceType(movedPiece) != PAWN) { // [HGM] Seirawan-style gating
+  if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE && piecetype(movedPiece) != PAWN) { // [HGM] Seirawan-style gating
     gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank];
     gs->board[mt->fromFile][mt->fromRank] = mt->piecePromotionTo | gs->onMove;;
     gs->holding[gs->onMove==WHITE ? 0 : 1][mt->piecePromotionTo-1]--; // remove gated piece from holdings