changes from H.G. Muller; version 4.3.14
[xboard.git] / moves.c
diff --git a/moves.c b/moves.c
index deac69f..edccef8 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -783,11 +783,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             (ignoreCheck ||                             \r
             (!CheckTest(board, flags, 0, ff, 0, ff + 1, FALSE) &&\r
               !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-3, FALSE) &&\r
+              (gameInfo.variant != VariantJanus || !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-2, FALSE)) &&\r
              !CheckTest(board, flags, 0, ff, 0, ff + 2, FALSE)))) {\r
 \r
            callback(board, flags,\r
                      ff==BOARD_WIDTH>>1 ? WhiteKingSideCastle : WhiteKingSideCastleWild,\r
-                     0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
+                     0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure);\r
        }\r
        if ((flags & F_WHITE_ON_MOVE) &&\r
            (flags & F_WHITE_QCASTLE_OK) &&\r
@@ -801,7 +802,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             ( castlingRights[2] == ff || castlingRights[6] == ff ) &&\r
            (ignoreCheck ||\r
             (!CheckTest(board, flags, 0, ff, 0, ff - 1, FALSE) &&\r
-              !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3,      FALSE) &&\r
+              !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3, FALSE) &&\r
              !CheckTest(board, flags, 0, ff, 0, ff - 2, FALSE)))) {\r
 \r
            callback(board, flags,\r
@@ -821,11 +822,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
            (ignoreCheck ||\r
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 1, FALSE) &&\r
               !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-3, FALSE) &&\r
+              (gameInfo.variant != VariantJanus || !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-2, FALSE)) &&\r
              !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 2, FALSE)))) {\r
 \r
            callback(board, flags,\r
                     ff==BOARD_WIDTH>>1 ? BlackKingSideCastle : BlackKingSideCastleWild,\r
-                     BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
+                     BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure);\r
        }\r
        if (!(flags & F_WHITE_ON_MOVE) &&\r
            (flags & F_BLACK_QCASTLE_OK) &&\r
@@ -839,7 +841,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             ( castlingRights[5] == ff || castlingRights[7] == ff ) &&\r
            (ignoreCheck ||\r
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 1, FALSE) &&\r
-              !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3,      FALSE) &&\r
+              !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3, FALSE) &&\r
               !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 2, FALSE)))) {\r
 \r
            callback(board, flags,\r
@@ -856,7 +858,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
 \r
     if ((flags & F_WHITE_ON_MOVE) != 0) {\r
         ff = castlingRights[2]; /* King file if we have any rights */\r
-        if(ff > 0) {\r
+        if(ff > 0 && board[0][ff] == WhiteKing) {\r
     if (appData.debugMode) {\r
         fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n",\r
                 castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]);\r
@@ -869,7 +871,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
                 if(k != ft && board[0][k] != EmptySquare) ft = -1;\r
             for(k=left; k<right && ft >= 0; k++) /* then if not checked */\r
                 if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;\r
-            if(ft >= 0)\r
+            if(ft >= 0 && board[0][ft] == WhiteRook)\r
                 callback(board, flags, WhiteHSideCastleFR, 0, ff, 0, ft, closure);\r
 \r
             ft = castlingRights[1]; /* Rook file if we have A-side rights */\r
@@ -881,13 +883,12 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             if(ff > BOARD_LEFT+2) \r
             for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */\r
                 if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;\r
-\r
-            if(ft >= 0)\r
+            if(ft >= 0 && board[0][ft] == WhiteRook)\r
                 callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure);\r
         }\r
     } else {\r
         ff = castlingRights[5]; /* King file if we have any rights */\r
-        if(ff > 0) {\r
+        if(ff > 0 && board[BOARD_HEIGHT-1][ff] == BlackKing) {\r
             ft = castlingRights[3]; /* Rook file if we have H-side rights */\r
             left  = ff+1;\r
             right = BOARD_RGHT-2;\r
@@ -896,7 +897,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
                 if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;\r
             for(k=left; k<right && ft >= 0; k++) /* then if not checked */\r
                 if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;\r
-            if(ft >= 0)\r
+            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)\r
                 callback(board, flags, BlackHSideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);\r
 \r
             ft = castlingRights[4]; /* Rook file if we have A-side rights */\r
@@ -908,8 +909,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             if(ff > BOARD_LEFT+2) \r
             for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */\r
                 if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;\r
-\r
-            if(ft >= 0)\r
+            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)\r
                 callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);\r
         }\r
     }\r
@@ -1144,7 +1144,7 @@ int MateTest(board, flags, epfile, castlingRights)
     if (cl.count > 0) {\r
        return inCheck ? MT_CHECK : MT_NONE;\r
     } else {\r
-        return inCheck || gameInfo.variant == VariantXiangqi ?\r
+        return inCheck || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj ?\r
                          MT_CHECKMATE : MT_STALEMATE;\r
     }\r
 }\r
@@ -1191,6 +1191,11 @@ void Disambiguate(board, flags, epfile, closure)
     closure->count = 0;\r
     closure->rf = closure->ff = closure->rt = closure->ft = 0;\r
     closure->kind = ImpossibleMove;\r
+    if (appData.debugMode) {\r
+        fprintf(debugFP, "Disambiguate in:  %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
+                             closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,\r
+                             closure->promoCharIn, closure->promoCharIn >= ' ' ? closure->promoCharIn : '-');\r
+    }\r
     GenLegal(board, flags, epfile, initialRights, DisambiguateCallback, (VOIDSTAR) closure);\r
     if (closure->count == 0) {\r
        /* See if it's an illegal move due to check */\r
@@ -1199,15 +1204,17 @@ void Disambiguate(board, flags, epfile, closure)
                 (VOIDSTAR) closure);   \r
        if (closure->count == 0) {\r
            /* No, it's not even that */\r
+    if (appData.debugMode) { int i, j;\r
+       for(i=BOARD_HEIGHT-1; i>=0; i--) {\r
+               for(j=0; j<BOARD_WIDTH; j++)\r
+                       fprintf(debugFP, "%3d", (int) board[i][j]);\r
+               fprintf(debugFP, "\n");\r
+       }\r
+    }\r
            return;\r
        }\r
     }\r
 \r
-    if (appData.debugMode) {\r
-        fprintf(debugFP, "Disambiguate in:  %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
-                             closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,\r
-                             closure->promoCharIn,closure->promoCharIn);\r
-    }\r
     if(gameInfo.variant == VariantShogi) {\r
         /* [HGM] Shogi promotions. '=' means defer */\r
         if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) {\r
@@ -1290,7 +1297,8 @@ void Disambiguate(board, flags, epfile, closure)
         closure->promoChar = closure->promoCharIn;\r
     if (appData.debugMode) {\r
         fprintf(debugFP, "Disambiguate out: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
-        closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar,closure->promoChar);\r
+        closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar,\r
+       closure->promoChar >= ' ' ? closure->promoChar:'-');\r
     }\r
 }\r
 \r
@@ -1374,7 +1382,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
     if(PieceToChar(piece)=='~') piece = (ChessSquare)(DEMOTED piece);\r
 \r
   if (appData.debugMode)\r
-          fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar );\r
+          fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar >= ' ' ? promoChar : '-');\r
     switch (piece) {\r
       case WhitePawn:\r
       case BlackPawn:\r
@@ -1406,7 +1414,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
        /* Use promotion suffix style "=Q" */\r
        *outp = NULLCHAR;\r
   if (appData.debugMode)\r
-          fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar);\r
+          fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar >= ' ' ? promoChar : '-');\r
         if (promoChar != NULLCHAR) {\r
             if(gameInfo.variant == VariantShogi) {\r
                 /* [HGM] ... but not in Shogi! */\r