X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=0d7a577d417e47d1b3f8680f939fd74cb7f0fe51;hb=85ceab43886403019cd91c13d4b9c366279227b6;hp=cb4d2843f0b8278383ac8af773fc5a7fcdbfe262;hpb=798c4449e01a9f8e2e64cd822e7a7f84a0b5dec0;p=xboard.git diff --git a/backend.c b/backend.c index cb4d284..0d7a577 100644 --- a/backend.c +++ b/backend.c @@ -296,6 +296,8 @@ int promoDefaultAltered; int keepInfo = 0; /* [HGM] to protect PGN tags in auto-step game analysis */ static int initPing = -1; int border; /* [HGM] width of board rim, needed to size seek graph */ +char bestMove[MSG_SIZ]; +int solvingTime, totalTime; /* States for ics_getting_history */ #define H_FALSE 0 @@ -8107,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; @@ -8793,6 +8795,17 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h free(fen); GameEnds(GameUnfinished, NULL, GE_XBOARD); } + if(appData.epd) { + if(solvingTime >= 0) { + snprintf(buf1, MSG_SIZ, "%d. %4.2fs\n", matchGame, solvingTime/100.); + totalTime += solvingTime; first.matchWins++; + } else { + snprintf(buf1, MSG_SIZ, "%d. wrong (%s)\n", matchGame, parseList[backwardMostMove]); + second.matchWins++; + } + OutputKibitz(2, buf1); + GameEnds(GameUnfinished, NULL, GE_XBOARD); + } /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */ if( gameMode == TwoMachinesPlay && appData.adjudicateLossThreshold != 0 && forwardMostMove >= adjudicateLossPlies ) { @@ -8970,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 @@ -8982,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; } @@ -9520,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); @@ -9542,6 +9556,14 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if(appData.pvSAN[cps==&second]) pv = PvToSAN(buf1); + if(*bestMove) { // rememer time best EPD move was first found + int ff1, tf1, fr1, tr1, ff2, tf2, fr2, tr2; char pp1, pp2; + ChessMove mt; + int ok = ParseOneMove(bestMove, forwardMostMove, &mt, &ff1, &fr1, &tf1, &tr1, &pp1); + ok &= ParseOneMove(pv, forwardMostMove, &mt, &ff2, &fr2, &tf2, &tr2, &pp2); + solvingTime = (ok && ff1==ff2 && fr1==fr2 && tf1==tf2 && tr1==tr2 && pp1==pp2 ? time : -1); + } + if(serverMoves && (time > 100 || time == 0 && plylev > 7)) { char buf[MSG_SIZ]; FILE *f; @@ -9612,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 ? " " : "" ); @@ -11392,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= 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; @@ -13312,10 +13341,14 @@ LoadPosition (FILE *f, int positionNumber, char *title) } if (fenMode) { + char *p; if (!ParseFEN(initial_position, &blackPlaysFirst, line, TRUE)) { DisplayError(_("Bad FEN position in file"), 0); return FALSE; } + if((p = strstr(line, ";")) && (p = strstr(p+1, "bm "))) { // EPD with best move + sscanf(p+3, "%s", bestMove); + } else *bestMove = NULLCHAR; } else { (void) fgets(line, MSG_SIZ, f); (void) fgets(line, MSG_SIZ, f);