Fix mate and stalemate test in Chu Shogi
authorH.G. Muller <h.g.muller@hccnet.nl>
Fri, 22 Nov 2013 22:40:33 +0000 (23:40 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Sun, 22 Dec 2013 22:32:09 +0000 (23:32 +0100)
Chu Shogi officially has no check, but we do want checkmate signs to
be displayed in SAN, and proper game-end messages to appear, rather than
force the user to play on until the King is captured. we also don't want
to allow him blundering away his King. So we don't use the F_IGNORE_CHECK
flag for Chu. But that means mate and stalemate will be recognized.
So it has to know stalemate is a win. Furthermore, check has to take
into account a possible spare royal. Finally, the + symbol to indicate
check should not be used in Chu, as in all Shogi variants this is reserved
to indicate promotion.

backend.c
moves.c

index 2db1405..8f796e7 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -4813,7 +4813,7 @@ ParseBoard12 (char *string)
              default:
                break;
              case MT_CHECK:
-                if(gameInfo.variant != VariantShogi)
+                if(!IS_SHOGI(gameInfo.variant))
                     strcat(parseList[moveNum - 1], "+");
                break;
              case MT_CHECKMATE:
@@ -9705,7 +9705,7 @@ ParseGameHistory (char *game)
          default:
            break;
          case MT_CHECK:
-            if(gameInfo.variant != VariantShogi)
+            if(!IS_SHOGI(gameInfo.variant))
                 strcat(parseList[boardIndex - 1], "+");
            break;
          case MT_CHECKMATE:
@@ -10147,7 +10147,7 @@ MakeMove (int fromX, int fromY, int toX, int toY, int promoChar)
       default:
        break;
       case MT_CHECK:
-        if(gameInfo.variant != VariantShogi)
+        if(!IS_SHOGI(gameInfo.variant))
             strcat(parseList[forwardMostMove - 1], "+");
        break;
       case MT_CHECKMATE:
diff --git a/moves.c b/moves.c
index fa41620..52b609c 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -1310,6 +1310,15 @@ CheckTest (Board board, int flags, int rf, int ff, int rt, int ft, int enPassant
         king = flags & F_WHITE_ON_MOVE ? WhiteWazir : BlackWazir;
     if(gameInfo.variant == VariantKnightmate)
         king = flags & F_WHITE_ON_MOVE ? WhiteUnicorn : BlackUnicorn;
+    if(gameInfo.variant == VariantChu) { // strictly speaking this is not needed, as Chu officially has no check
+       int r, f, k = king, royals=0, prince = flags & F_WHITE_ON_MOVE ? WhiteMonarch : BlackMonarch;
+       for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) {
+           if(board[r][f] == k || board[r][f] == prince) {
+               if(++royals > 1) return FALSE; // no check if we have two royals (ignores double captureby Lion!)
+               king = board[r][f]; // remember hich one we had
+           }
+       }
+    }
 
     if (rt >= 0) {
        if (enPassant) {
@@ -1618,7 +1627,7 @@ MateTest (Board board, int flags)
        else if(gameInfo.variant == VariantGiveaway) return MT_STEALMATE; // no check exists, stalemated = win
 
         return inCheck ? MT_CHECKMATE
-                      : (gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj || gameInfo.variant == VariantShogi) ?
+                      : (gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj || IS_SHOGI(gameInfo.variant)) ?
                          MT_STAINMATE : MT_STALEMATE;
     }
 }