Fix bare-king adjudication in Atomic
[xboard.git] / backend.c
index f1dcf5d..0d7a577 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -8109,7 +8109,7 @@ Adjudicate (ChessProgramState *cps)
        // most tests only when we understand the game, i.e. legality-checking on
            if( appData.testLegality )
            {   /* [HGM] Some more adjudications for obstinate engines */
-               int nrW, nrB, bishopColor, staleW, staleB, nr[EmptySquare+1], i;
+               int nrW, nrB, bishopColor, staleW, staleB, nr[EmptySquare+2], i;
                static int moveCount = 6;
                ChessMove result;
                char *reason = NULL;
@@ -8983,7 +8983,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
       char *p=buf2, *q, *s = SUFFIXES, ID = *p;
       if(*p == '+') piece = CHUPROMOTED WhitePawn, ID = *++p;
       if(q = strchr(s, p[1])) ID += 64*(q - s + 1), p++;
-      piece += CharToPiece(ID) - WhitePawn;
+      piece += CharToPiece(ID & 255) - WhitePawn;
       if(cps != &first || appData.testLegality && *engineVariant == NULLCHAR
       /* always accept definition of  */       && piece != WhiteFalcon && piece != BlackFalcon
       /* wild-card pieces.            */       && piece != WhiteCobra  && piece != BlackCobra
@@ -8995,7 +8995,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
       if(piece < EmptySquare) {
         pieceDefs = TRUE;
         ASSIGN(pieceDesc[piece], buf1);
-        if(isupper(*p) && p[1] == '&') { ASSIGN(pieceDesc[WHITE_TO_BLACK piece], buf1); }
+        if((ID & 32) == 0 && p[1] == '&') { ASSIGN(pieceDesc[WHITE_TO_BLACK piece], buf1); }
       }
       return;
     }
@@ -9533,6 +9533,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            buf1[0] = NULLCHAR;
            if (sscanf(message, "%d%c %d %d " u64Display " %[^\n]\n",
                       &plylev, &plyext, &curscore, &time, &nodes, buf1) >= 5) {
+               char score_buf[MSG_SIZ];
 
                if(nodes>>32 == u64Const(0xFFFFFFFF))   // [HGM] negative node count read
                    nodes += u64Const(0x100000000);
@@ -9633,11 +9634,17 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                     [AS] Protect the thinkOutput buffer from overflow... this
                     is only useful if buf1 hasn't overflowed first!
                 */
-               snprintf(thinkOutput, sizeof(thinkOutput)/sizeof(thinkOutput[0]), "[%d]%c%+.2f %s%s",
+               if(curscore >= MATE_SCORE) 
+                   snprintf(score_buf, MSG_SIZ, "#%d", curscore - MATE_SCORE);
+               else if(curscore <= -MATE_SCORE) 
+                   snprintf(score_buf, MSG_SIZ, "#%d", curscore + MATE_SCORE);
+               else
+                   snprintf(score_buf, MSG_SIZ, "%+.2f", ((double) curscore) / 100.0);
+               snprintf(thinkOutput, sizeof(thinkOutput)/sizeof(thinkOutput[0]), "[%d]%c%s %s%s",
                         plylev,
                         (gameMode == TwoMachinesPlay ?
                          ToUpper(cps->twoMachinesColor[0]) : ' '),
-                        ((double) curscore) / 100.0,
+                        score_buf,
                         prefixHint ? lastHint : "",
                         prefixHint ? " " : "" );
 
@@ -11413,16 +11420,17 @@ GameEnds (ChessMove result, char *resultDetails, int whosays)
               && gameInfo.variant != VariantLosers && gameInfo.variant != VariantGiveaway
               && gameInfo.variant != VariantSuicide // [HGM] losers: except in losers, of course...
               && result != GameIsDrawn)
-           {   int i, j, k=0, color = (result==WhiteWins ? (int)WhitePawn : (int)BlackPawn);
+           {   int i, j, k=0, oppoKings = 0, color = (result==WhiteWins ? (int)WhitePawn : (int)BlackPawn);
                for(j=BOARD_LEFT; j<BOARD_RGHT; j++) for(i=0; i<BOARD_HEIGHT; i++) {
                        int p = (signed char)boards[forwardMostMove][i][j] - color;
                        if(p >= 0 && p <= (int)WhiteKing) k++;
+                       oppoKings += (p + color == WhiteKing + BlackPawn - color);
                }
                if (appData.debugMode) {
                     fprintf(debugFP, "GE(%d, %s, %d) bare king k=%d color=%d\n",
                        result, resultDetails ? resultDetails : "(null)", whosays, k, color);
                }
-               if(k <= 1) {
+               if(k <= 1 && oppoKings > 0) { // the latter needed in Atomic, where bare K wins if opponent King already destroyed
                        result = GameIsDrawn;
                        snprintf(buf, MSG_SIZ, "%s but bare king", resultDetails);
                        resultDetails = buf;