X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=bd37f6daf7526652d58244f7c3745db529ce1e2f;hb=4d3fc238587cf474577210196630a69530cd7c2b;hp=125fd3de4590026beac1ae7e719841903414a149;hpb=e921ccb3b79c9cfc5657e715eb50b5d9ed298db8;p=xboard.git diff --git a/backend.c b/backend.c index 125fd3d..bd37f6d 100644 --- a/backend.c +++ b/backend.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -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 @@ -5228,7 +5230,7 @@ SendMoveToICS (ChessMove moveType, int fromX, int fromY, int toX, int toY, char case WhitePromotion: case BlackPromotion: if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) + gameInfo.variant == VariantMakruk) snprintf(user_move, MSG_SIZ, "%c%c%c%c=%c\n", AAA + fromX, ONE + fromY, AAA + toX, ONE + toY, PieceToChar(WhiteFerz)); @@ -5334,11 +5336,11 @@ UploadGameEvent () SendToICS(ics_type == ICS_ICC ? "tag result Game in progress\n" : "commit\n"); } -int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove +int killX = -1, killY = -1, kill2X = -1, kill2Y = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove int legNr = 1; void -CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char move[7]) +CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char move[9]) { if (rf == DROP_RANK) { if(ff == EmptySquare) sprintf(move, "@@@@\n"); else // [HGM] pass @@ -5348,7 +5350,10 @@ CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char if (promoChar == 'x' || promoChar == NULLCHAR) { sprintf(move, "%c%c%c%c\n", AAA + ff, ONE + rf, AAA + ft, ONE + rt); - if(killX >= 0 && killY >= 0) sprintf(move+4, ";%c%c\n", AAA + killX, ONE + killY); + if(killX >= 0 && killY >= 0) { + sprintf(move+4, ";%c%c\n", AAA + killX, ONE + killY); + if(kill2X >= 0 && kill2Y >= 0) sprintf(move+7, "%c%c\n", AAA + killX, ONE + killY); + } } else { sprintf(move, "%c%c%c%c%c\n", AAA + ff, ONE + rf, AAA + ft, ONE + rt, promoChar); @@ -6553,8 +6558,10 @@ DefaultPromoChoice (int white) { ChessSquare result; if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) + gameInfo.variant == VariantMakruk) result = WhiteFerz; // no choice + else if(gameInfo.variant == VariantASEAN) + result = WhiteRook; // no choice else if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway) result= WhiteKing; // in Suicide Q is the last thing we want else if(gameInfo.variant == VariantSpartan) @@ -6646,7 +6653,7 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i // we either have a choice what to promote to, or (in Shogi) whether to promote if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) { + gameInfo.variant == VariantMakruk) { ChessSquare p=BlackFerz; // no choice while(p < EmptySquare) { //but make sure we use piece that exists *promoChoice = PieceToChar(p++); @@ -7358,7 +7365,7 @@ CanPromote (ChessSquare piece, int y) if(IS_SHOGI(gameInfo.variant) || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat || gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) return FALSE; + gameInfo.variant == VariantMakruk) return FALSE; return (piece == BlackPawn && y <= zone || piece == WhitePawn && y >= BOARD_HEIGHT-1-zone || piece == BlackLance && y <= zone || @@ -7707,7 +7714,9 @@ printf("(%d,%d)-(%d,%d) %d %d\n",fromX,fromY,toX,toY,x,y); if(marker[y][x] == 5) { // [HGM] lion: this was the release of a to-click or drag on a cyan square dragging *= 2; // flag button-less dragging if we are dragging MarkTargetSquares(1); - if(x == killX && y == killY) killX = killY = -1; else { + if(x == killX && y == killY) killX = kill2X, killY = kill2Y, kill2X = kill2Y = -1; // cancel last kill + else { + kill2X = killX; kill2Y = killY; killX = x; killY = y; //remeber this square as intermediate ReportClick("put", x, y); // and inform engine ReportClick("lift", x, y); @@ -8692,7 +8701,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if(cps->alphaRank) AlphaRank(machineMove, 4); // [HGM] lion: (some very limited) support for Alien protocol - killX = killY = -1; + killX = killY = kill2X = kill2Y = -1; if(machineMove[strlen(machineMove)-1] == ',') { // move ends in coma: non-final leg of composite move safeStrCpy(firstLeg, machineMove, 20); // just remember it for processing when second leg arrives return; @@ -8720,8 +8729,8 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h snprintf(buf1, MSG_SIZ*10, _("Illegal move \"%s\" from %s machine"), machineMove, _(cps->which)); DisplayMoveError(buf1); - snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to invalid move: %s (%c%c%c%c via %c%c) res=%d", - machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, killX+AAA, killY+ONE, moveType); + snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to invalid move: %s (%c%c%c%c via %c%c, %c%c) res=%d", + machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, killX+AAA, killY+ONE, kill2X+AAA, kill2Y+ONE, moveType); if (gameMode == TwoMachinesPlay) { GameEnds(machineWhite ? BlackWins : WhiteWins, buf1, GE_XBOARD); @@ -8786,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 ) { @@ -9098,7 +9118,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h return; } if(!strncmp(message, "highlight ", 10)) { - if((appData.testLegality || *engineVariant) && appData.markers) return; + if(appData.testLegality && !*engineVariant && appData.markers) return; MarkByFEN(message+10); // [HGM] alien: allow engine to mark board squares return; } @@ -9513,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); @@ -9535,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; @@ -9605,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 ? " " : "" ); @@ -9951,7 +9986,7 @@ ParseGameHistory (char *game) void ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) { - ChessSquare captured = board[toY][toX], piece, pawn, king, killed; int p, rookX, oldEP, epRank, berolina = 0; + ChessSquare captured = board[toY][toX], piece, pawn, king, killed, killed2; int p, rookX, oldEP, epRank, berolina = 0; int promoRank = gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess ? 3 : 1; /* [HGM] compute & store e.p. status and castling rights for new position */ @@ -9973,11 +10008,14 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) // ChessSquare victim; int i; - if( killX >= 0 && killY >= 0 ) // [HGM] lion: Lion trampled over something + if( killX >= 0 && killY >= 0 ) { // [HGM] lion: Lion trampled over something // victim = board[killY][killX], killed = board[killY][killX], board[killY][killX] = EmptySquare, board[EP_STATUS] = EP_CAPTURE; + if( kill2X >= 0 && kill2Y >= 0) + killed2 = board[kill2Y][kill2X], board[kill2Y][kill2X] = EmptySquare; + } if( board[toY][toX] != EmptySquare ) { board[EP_STATUS] = EP_CAPTURE; @@ -13302,10 +13340,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);