Fix parsing of O-O and O-O-O after FEN pasting in FRC
[xboard.git] / backend.c
index 74898c8..3480a11 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -3155,6 +3155,7 @@ read_from_ics(isr, closure, data, count, error)
                    strncmp(why, "Continuing ", 11) == 0) {
                    gs_gamenum = gamenum;
                    strcpy(gs_kind, strchr(why, ' ') + 1);
+                   VariantSwitch(boards[currentMove], StringToVariant(gs_kind)); // [HGM] variantswitch: even before we get first board
 #if ZIPPY
                    if (appData.zippyPlay) {
                        ZippyGameStart(whitename, blackname);
@@ -3704,16 +3705,16 @@ ParseBoard12(string)
     if(moveNum == 0 || gameInfo.variant != VariantFischeRandom)
     { int i, j; ChessSquare wKing = WhiteKing, bKing = BlackKing;
 
-        for(i=BOARD_LEFT, j= -1; i<BOARD_RGHT; i++)
+        for(i=BOARD_LEFT, j=NoRights; i<BOARD_RGHT; i++)
             if(board[0][i] == WhiteRook) j = i;
         initialRights[0] = boards[moveNum][CASTLING][0] = (castle_ws == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
-        for(i=BOARD_RGHT-1, j= -1; i>=BOARD_LEFT; i--)
+        for(i=BOARD_RGHT-1, j=NoRights; i>=BOARD_LEFT; i--)
             if(board[0][i] == WhiteRook) j = i;
         initialRights[1] = boards[moveNum][CASTLING][1] = (castle_wl == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
-        for(i=BOARD_LEFT, j= -1; i<BOARD_RGHT; i++)
+        for(i=BOARD_LEFT, j=NoRights; i<BOARD_RGHT; i++)
             if(board[BOARD_HEIGHT-1][i] == BlackRook) j = i;
         initialRights[3] = boards[moveNum][CASTLING][3] = (castle_bs == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
-        for(i=BOARD_RGHT-1, j= -1; i>=BOARD_LEFT; i--)
+        for(i=BOARD_RGHT-1, j=NoRights; i>=BOARD_LEFT; i--)
             if(board[BOARD_HEIGHT-1][i] == BlackRook) j = i;
         initialRights[4] = boards[moveNum][CASTLING][4] = (castle_bl == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
 
@@ -3723,6 +3724,11 @@ ParseBoard12(string)
         for(k=BOARD_LEFT; k<BOARD_RGHT; k++)
             if(board[BOARD_HEIGHT-1][k] == bKing)
                 initialRights[5] = boards[moveNum][CASTLING][5] = k;
+        if(gameInfo.variant == VariantTwoKings) {
+            // In TwoKings looking for a King does not work, so always give castling rights to a King on e1/e8
+            if(board[0][4] == wKing) initialRights[2] = boards[moveNum][CASTLING][2] = 4;
+            if(board[BOARD_HEIGHT-1][4] == bKing) initialRights[5] = boards[moveNum][CASTLING][5] = 4;
+        }
     } else { int r;
         r = boards[moveNum][CASTLING][0] = initialRights[0];
         if(board[0][r] != WhiteRook) boards[moveNum][CASTLING][0] = NoRights;
@@ -14133,10 +14139,12 @@ ParseFEN(board, blackPlaysFirst, fen)
     }   /* assume possible unless obviously impossible */
     if(initialRights[0]!=NoRights && board[castlingRank[0]][initialRights[0]] != WhiteRook) board[CASTLING][0] = NoRights;
     if(initialRights[1]!=NoRights && board[castlingRank[1]][initialRights[1]] != WhiteRook) board[CASTLING][1] = NoRights;
-    if(initialRights[2]!=NoRights && board[castlingRank[2]][initialRights[2]] != WhiteKing) board[CASTLING][2] = NoRights;
+    if(initialRights[2]!=NoRights && board[castlingRank[2]][initialRights[2]] != WhiteUnicorn
+                                 && board[castlingRank[2]][initialRights[2]] != WhiteKing) board[CASTLING][2] = NoRights;
     if(initialRights[3]!=NoRights && board[castlingRank[3]][initialRights[3]] != BlackRook) board[CASTLING][3] = NoRights;
     if(initialRights[4]!=NoRights && board[castlingRank[4]][initialRights[4]] != BlackRook) board[CASTLING][4] = NoRights;
-    if(initialRights[5]!=NoRights && board[castlingRank[5]][initialRights[5]] != BlackKing) board[CASTLING][5] = NoRights;
+    if(initialRights[5]!=NoRights && board[castlingRank[5]][initialRights[5]] != BlackUnicorn
+                                 && board[castlingRank[5]][initialRights[5]] != BlackKing) board[CASTLING][5] = NoRights;
     FENrulePlies = 0;
 
     while(*p==' ') p++;
@@ -14151,12 +14159,18 @@ ParseFEN(board, blackPlaysFirst, fen)
              (gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) &&
              ( *p >= 'a' && *p < 'a' + gameInfo.boardWidth) ||
              ( *p >= 'A' && *p < 'A' + gameInfo.boardWidth)   ) {
-        char c = *p++; int whiteKingFile=-1, blackKingFile=-1;
+        char c = *p++; int whiteKingFile=NoRights, blackKingFile=NoRights;
 
         for(i=BOARD_LEFT; i<BOARD_RGHT; i++) {
             if(board[BOARD_HEIGHT-1][i] == BlackKing) blackKingFile = i;
             if(board[0             ][i] == WhiteKing) whiteKingFile = i;
         }
+        if(gameInfo.variant == VariantTwoKings || gameInfo.variant == VariantKnightmate)
+            whiteKingFile = blackKingFile = BOARD_WIDTH >> 1; // for these variant scanning fails
+        if(whiteKingFile == NoRights || board[0][whiteKingFile] != WhiteUnicorn
+                                     && board[0][whiteKingFile] != WhiteKing) whiteKingFile = NoRights;
+        if(blackKingFile == NoRights || board[BOARD_HEIGHT-1][blackKingFile] != BlackUnicorn
+                                     && board[BOARD_HEIGHT-1][blackKingFile] != BlackKing) blackKingFile = NoRights;
         switch(c) {
           case'K':
               for(i=BOARD_RGHT-1; board[0][i]!=WhiteRook && i>whiteKingFile; i--);
@@ -14164,7 +14178,7 @@ ParseFEN(board, blackPlaysFirst, fen)
               board[CASTLING][2] = whiteKingFile;
               break;
           case'Q':
-              for(i=BOARD_LEFT; board[0][i]!=WhiteRook && i<whiteKingFile; i++);
+              for(i=BOARD_LEFT;  i<BOARD_RGHT && board[0][i]!=WhiteRook && i<whiteKingFile; i++);
               board[CASTLING][1] = i != whiteKingFile ? i : NoRights;
               board[CASTLING][2] = whiteKingFile;
               break;
@@ -14174,7 +14188,7 @@ ParseFEN(board, blackPlaysFirst, fen)
               board[CASTLING][5] = blackKingFile;
               break;
           case'q':
-              for(i=BOARD_LEFT; board[BOARD_HEIGHT-1][i]!=BlackRook && i<blackKingFile; i++);
+              for(i=BOARD_LEFT; i<BOARD_RGHT && board[BOARD_HEIGHT-1][i]!=BlackRook && i<blackKingFile; i++);
               board[CASTLING][4] = i != blackKingFile ? i : NoRights;
               board[CASTLING][5] = blackKingFile;
           case '-':
@@ -14206,6 +14220,8 @@ ParseFEN(board, blackPlaysFirst, fen)
               }
         }
       }
+      for(i=0; i<nrCastlingRights; i++)
+        if(board[CASTLING][i] != NoRights) initialRights[i] = board[CASTLING][i];
     if (appData.debugMode) {
         fprintf(debugFP, "FEN castling rights:");
         for(i=0; i<nrCastlingRights; i++)