Awareness of winning conditions for atomic and giveaway variants; two bugfixes
authorH.G. Muller <h.g.muller@hccnet.nl>
Sat, 13 Jun 2009 16:19:05 +0000 (09:19 -0700)
committerArun Persaud <arun@nubati.net>
Sat, 13 Jun 2009 16:19:05 +0000 (09:19 -0700)
fixed bug in claim verification
Bugfix on initial position of Great Shatranj

backend.c

index face7f1..711d1e0 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -351,6 +351,8 @@ PosFlags(index)
     flags &= ~F_ALL_CASTLE_OK;\r
   case VariantGiveaway:                // [HGM] moved this case label one down: seems Giveaway does have castling on ICC!\r
     flags |= F_IGNORE_CHECK;\r
+  case VariantLosers:\r
+    flags |= F_MANDATORY_CAPTURE; //[HGM] losers: sets flag so TestLegality rejects non-capts if capts exist\r
     break;\r
   case VariantAtomic:\r
     flags |= F_IGNORE_CHECK | F_ATOMIC_CAPTURE;\r
@@ -4792,8 +4794,8 @@ InitPosition(redraw)
 \r
      if(gameInfo.variant == VariantSuper) Prelude(initialPosition);\r
      if(gameInfo.variant == VariantGreat) { // promotion commoners\r
-       initialPosition[PieceToNumber(WhiteMan)][BOARD_RGHT-1] = WhiteMan;\r
-       initialPosition[PieceToNumber(WhiteMan)][BOARD_RGHT-2] = 9;\r
+       initialPosition[PieceToNumber(WhiteMan)][BOARD_WIDTH-1] = WhiteMan;\r
+       initialPosition[PieceToNumber(WhiteMan)][BOARD_WIDTH-2] = 9;\r
        initialPosition[BOARD_HEIGHT-1-PieceToNumber(WhiteMan)][0] = BlackMan;\r
        initialPosition[BOARD_HEIGHT-1-PieceToNumber(WhiteMan)][1] = 9;\r
      }\r
@@ -5810,8 +5812,13 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                 if(appData.checkMates) {\r
                    SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */\r
                    ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
-                   GameEnds( GameIsDrawn, "Xboard adjudication: Stalemate",\r
-                       GE_XBOARD );\r
+                   if(gameInfo.variant == VariantLosers || gameInfo.variant == VariantSuicide\r
+                                                        || gameInfo.variant == VariantGiveaway) // [HGM] losers:\r
+                       GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, // stalemated side wins!\r
+                               "Xboard adjudication: Stalemate", GE_XBOARD );\r
+                   else\r
+                       GameEnds( GameIsDrawn, "Xboard adjudication: Stalemate", GE_XBOARD );\r
+                   return;\r
                }\r
                break;\r
              case MT_CHECKMATE:\r
@@ -5819,9 +5826,10 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                 if(appData.checkMates) {\r
                    SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */\r
                    ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
-                   GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins, \r
-                   "Xboard adjudication: Checkmate", \r
-                   GE_XBOARD );\r
+                   GameEnds( WhiteOnMove(forwardMostMove) != (gameInfo.variant == VariantLosers) // [HGM] losers:\r
+                            ? BlackWins : WhiteWins,            // reverse the result ( A!=1 is !A for a boolean)\r
+                            "Xboard adjudication: Checkmate", GE_XBOARD );\r
+                   return;\r
                }\r
                break;\r
            }\r
@@ -5829,7 +5837,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            if( appData.testLegality )\r
            {   /* [HGM] Some more adjudications for obstinate engines */\r
                int NrWN=0, NrBN=0, NrWB=0, NrBB=0, NrWR=0, NrBR=0,\r
-                    NrWQ=0, NrBQ=0, NrW=0, bishopsColor = 0,\r
+                    NrWQ=0, NrBQ=0, NrW=0, NrK=0, bishopsColor = 0,\r
                     NrPieces=0, NrPawns=0, PawnAdvance=0, i, j;\r
                static int moveCount = 6;\r
 \r
@@ -5840,6 +5848,9 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
 \r
                    switch((int) p)\r
                    {   /* count B,N,R and other of each side */\r
+                        case WhiteKing:\r
+                        case BlackKing:\r
+                            NrK++; break; // [HGM] atomic: count Kings\r
                         case WhiteKnight:\r
                              NrWN++; break;\r
                         case WhiteBishop:\r
@@ -5876,6 +5887,45 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                    }\r
                 }\r
 \r
+               if(gameInfo.variant == VariantAtomic && NrK < 2) {\r
+                   // [HGM] atomic: stm must have lost his King on previous move, as destroying own K is illegal\r
+                    epStatus[forwardMostMove] = EP_CHECKMATE; // make claimable as if stm is checkmated\r
+                    if(appData.checkMates) {\r
+                        SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move\r
+                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
+                         GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins, \r
+                                                       "Xboard adjudication: King destroyed", GE_XBOARD );\r
+                         return;\r
+                    }\r
+               }\r
+\r
+               /* Bare King in Shatranj (loses) or Losers (wins) */\r
+                if( NrW == 1 || NrPieces - NrW == 1) {\r
+                  if( gameInfo.variant == VariantLosers) { // [HGM] losers: bare King wins (stm must have it first)\r
+                    epStatus[forwardMostMove] = EP_STALEMATE; // kludge to make position claimable as win\r
+                    if(appData.checkMates) {\r
+                        SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */\r
+                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
+                         GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, \r
+                                                       "Xboard adjudication: Bare king", GE_XBOARD );\r
+                         return;\r
+                    }\r
+                 } else\r
+                  if( gameInfo.variant == VariantShatranj && --bare < 0)\r
+                  {    /* bare King */\r
+                       epStatus[forwardMostMove] = EP_CHECKMATE; // make claimable as win for stm\r
+                       if(appData.checkMates) {\r
+                           /* but only adjudicate if adjudication enabled */\r
+                           SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move\r
+                           ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
+                           GameEnds( NrW > 1 ? WhiteWins : NrPieces - NrW > 1 ? BlackWins : GameIsDrawn, \r
+                                                       "Xboard adjudication: Bare king", GE_XBOARD );\r
+                           return;\r
+                       }\r
+                 }\r
+                } else bare = 1;\r
+\r
+\r
                 if( NrPieces == 2 || gameInfo.variant != VariantXiangqi && \r
                                     gameInfo.variant != VariantShatranj && // [HGM] baring will remain possible\r
                        (NrPieces == 3 && NrWN+NrBN+NrWB+NrBB == 1 ||\r
@@ -5895,20 +5945,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                      }\r
                 }\r
 \r
-               /* Shatranj baring rule */\r
-                if( gameInfo.variant == VariantShatranj && (NrW == 1 || NrPieces - NrW == 1) )\r
-                {    /* bare King */\r
-\r
-                     if(--bare < 0 && appData.checkMates) {\r
-                         /* but only adjudicate them if adjudication enabled */\r
-                        SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */\r
-                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/\r
-                         GameEnds( NrW > 1 ? WhiteWins : NrPieces - NrW > 1 ? BlackWins : GameIsDrawn, \r
-                                                       "Xboard adjudication: Bare king", GE_XBOARD );\r
-                         return;\r
-                     }\r
-                } else bare = 1;\r
-\r
                 /* Then some trivial draws (only adjudicate, cannot be claimed) */\r
                 if(NrPieces == 4 && \r
                    (   NrWR == 1 && NrBR == 1 /* KRKR */\r
@@ -7794,20 +7830,35 @@ GameEnds(result, resultDetails, whosays)
         if(gameMode == TwoMachinesPlay && appData.testClaims) {\r
            if(appData.testLegality && whosays >= GE_ENGINE1 ) {\r
                 char claimer;\r
+               ChessMove trueResult = (ChessMove) -1;\r
 \r
                 claimer = whosays == GE_ENGINE1 ?      /* color of claimer */\r
                                             first.twoMachinesColor[0] :\r
                                             second.twoMachinesColor[0] ;\r
-                if( (gameInfo.holdingsWidth == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) &&\r
-                    (result == WhiteWins && claimer == 'w' ||\r
-                     result == BlackWins && claimer == 'b'   ) ) {\r
-               if (appData.debugMode) {\r
-                    fprintf(debugFP, "result=%d sp=%d move=%d\n",\r
-                       result, epStatus[forwardMostMove], forwardMostMove);\r
+\r
+               // [HGM] losers: because the logic is becoming a bit hairy, determine true result first\r
+               if(epStatus[forwardMostMove] == EP_CHECKMATE) {\r
+                   /* [HGM] verify: engine mate claims accepted if they were flagged */\r
+                   trueResult = WhiteOnMove(forwardMostMove) != (gameInfo.variant == VariantLosers)\r
+                       ? BlackWins : WhiteWins; // [HGM] losers: reverse the result in VariantLosers!\r
+               } else\r
+               if(epStatus[forwardMostMove] == EP_STALEMATE) {\r
+                   trueResult = GameIsDrawn; // default; in variants where stalemate loses, Status is CHECKMATE\r
+                   if(gameInfo.variant == VariantGiveaway || gameInfo.variant == VariantSuicide || \r
+                      gameInfo.variant == VariantLosers)  // [HGM] losers: in giveaway variants stalemate wins\r
+                       trueResult = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins;\r
                }\r
-                      /* [HGM] verify: engine mate claims accepted if they were flagged */\r
-                     if(epStatus[forwardMostMove] != EP_CHECKMATE &&\r
-                        result != (WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins)) {\r
+\r
+               // now verify win claims, but not in drop games, as we don't understand those yet\r
+                if( (gameInfo.holdingsWidth == 0 || gameInfo.variant == VariantSuper\r
+                                                || gameInfo.variant == VariantGreat) &&\r
+                    (result == WhiteWins && claimer == 'w' ||\r
+                     result == BlackWins && claimer == 'b'   ) ) { // case to verify: engine claims own win\r
+                     if (appData.debugMode) {\r
+                       fprintf(debugFP, "result=%d sp=%d move=%d\n",\r
+                               result, epStatus[forwardMostMove], forwardMostMove);\r
+                     }\r
+                     if(result != trueResult) {\r
                              sprintf(buf, "False win claim: '%s'", resultDetails);\r
                              result = claimer == 'w' ? BlackWins : WhiteWins;\r
                              resultDetails = buf;\r