Fix Seirawan gating at Rook square in PGN castling moves
[xboard.git] / moves.c
diff --git a/moves.c b/moves.c
index 30f94b5..a6b066b 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -170,7 +170,7 @@ CopyBoard (Board to, Board from)
 {
     int i, j;
 
-    for (i = 0; i < BOARD_HEIGHT; i++)
+    for (i = 0; i < handSize; i++)
       for (j = 0; j < BOARD_WIDTH; j++)
        to[i][j] = from[i][j];
     for (j = 0; j < BOARD_FILES; j++) // [HGM] gamestate: copy castling rights and ep status
@@ -809,7 +809,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                               rf, ff, rf + 1, ff + s, closure);
                  }
                  if (rf >= BOARD_HEIGHT+1>>1) {// [HGM] grand: 4th & 5th rank on 10-board
-                     int victimFile = (board[LAST_FILE] == 100 ? ff + s : board[LAST_FILE]);
+                     int victimFile = (board[LAST_TO] & 0x40 ? ff + s : board[LAST_TO] & 255);
                       if (ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&
                          (board[EP_FILE] == ff + s || epfile == EP_UNKNOWN) && rf < BOARD_HEIGHT-3 &&
                           (board[rf][victimFile] == BlackPawn || board[rf][victimFile] == BlackLance) &&
@@ -860,7 +860,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                               rf, ff, rf - 1, ff + s, closure);
                  }
                  if (rf < BOARD_HEIGHT>>1) {
-                     int victimFile = (board[LAST_FILE] == 100 ? ff + s : board[LAST_FILE]);
+                     int victimFile = (board[LAST_TO] & 0x40 ? ff + s : board[LAST_TO] & 255);
                       if (ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&
                          (board[EP_FILE] == ff + s || epfile == EP_UNKNOWN) && rf > 2 &&
                          (board[rf][victimFile] == WhitePawn || board[rf][victimFile] == WhiteLance) &&
@@ -1826,7 +1826,7 @@ LegalDrop (Board board, int flags, ChessSquare piece, int rt, int ft)
 if(appData.debugMode) fprintf(debugFP, "LegalDrop: %d @ %d,%d)\n", piece, ft, rt);
     if(board[rt][ft] != EmptySquare) return ImpossibleMove; // must drop to empty square
     n = PieceToNumber(piece);
-    if((gameInfo.holdingsWidth == 0 || (flags & F_WHITE_ON_MOVE ? board[n][BOARD_WIDTH-1] : board[BOARD_HEIGHT-1-n][0]) != piece)
+    if((gameInfo.holdingsWidth == 0 || (flags & F_WHITE_ON_MOVE ? board[n][BOARD_WIDTH-1] : board[handSize-1-n][0]) != piece)
        && gameInfo.variant != VariantBughouse) // in bughouse we don't check for availability, because ICS doesn't always tell us
         return ImpossibleMove; // piece not available
     if(gameInfo.variant == VariantShogi) { // in Shogi lots of drops are forbidden!
@@ -2401,9 +2401,9 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p
             ((ff == BOARD_WIDTH>>1 && (ft == BOARD_LEFT+2 || ft == BOARD_RGHT-2)) ||
              (ff == (BOARD_WIDTH-1)>>1 && (ft == BOARD_LEFT+1 || ft == BOARD_RGHT-3)))) {
             if(ft==BOARD_LEFT+1 || ft==BOARD_RGHT-2)
-             snprintf(out, MOVE_LEN, "O-O%c%c", promoChar ? '/' : 0, ToUpper(promoChar));
+             snprintf(out, MOVE_LEN, "O-O%c%c%c", promoChar ? '/' : 0, ToUpper(promoChar), ff + AAA);
             else
-             snprintf(out, MOVE_LEN, "O-O-O%c%c", promoChar ? '/' : 0, ToUpper(promoChar));
+             snprintf(out, MOVE_LEN, "O-O-O%c%c%c", promoChar ? '/' : 0, ToUpper(promoChar), ff + AAA);
 
            /* This notation is always unambiguous, unless there are
               kings on both the d and e files, with "wild castling"
@@ -2478,8 +2478,15 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p
             *outp++ = ToUpper(promoChar);
         }
         else if (gameInfo.variant == VariantSChess && promoChar) { // and in S-Chess we have gating
+            ChessSquare victim = board[rt][ft];
+            if(piece == WhiteRook && victim == WhiteKing ||
+               piece == BlackRook && victim == BlackKing) {
+                strncpy(out, "O-O-O", MOVE_LEN);
+                outp = out + 3 + 2*(ft > ff);
+            }
             *outp++ = '/';
             *outp++ = ToUpper(promoChar);
+            if(out[0] == 'O') *outp++ = ff + AAA;
         }
        *outp = NULLCHAR;
         return cl.kind;