}\r
if(nrAlph < 9*nrDigit) { // if more than 10% digit we assume search info\r
int depth=0; float score;\r
- if(sscanf(parse, "%f/%d", &score, &depth) == 2 && depth>0) {\r
+ if(sscanf(parse, "!!! %f/%d", &score, &depth) == 2 && depth>0) {\r
// [HGM] kibitz: save kibitzed opponent info for PGN and eval graph\r
pvInfoList[forwardMostMove-1].depth = depth;\r
pvInfoList[forwardMostMove-1].score = 100*score;\r
strcat(parseList[moveNum - 1], "+");\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE: // [HGM] xq: for notation stalemate that wins counts as checkmate\r
strcat(parseList[moveNum - 1], "#");\r
break;\r
}\r
case MT_CHECK:\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
if (WhiteOnMove(currentMove)) {\r
GameEnds(BlackWins, "Black mates", GE_PLAYER);\r
} else {\r
if(appData.autoKibitz && !appData.icsEngineAnalyze ) { /* [HGM] kibitz: send most-recent PV info to ICS */\r
char buf[3*MSG_SIZ];\r
\r
- sprintf(buf, "kibitz %+.2f/%d (%.2f sec, %.0f nodes, %1.0f knps) PV=%s\n",\r
+ sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %.0f nodes, %1.0f knps) PV=%s\n",\r
programStats.score / 100.,\r
programStats.depth,\r
programStats.time / 100.,\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
+ ChessMove result;\r
+ char *reason = NULL;\r
\r
/* Count what is on board. */\r
for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++)\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
+ epStatus[forwardMostMove] = EP_WINS; // mark as win, so it becomes claimable\r
if(appData.checkMates) {\r
- SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */\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
} else\r
if( gameInfo.variant == VariantShatranj && --bare < 0)\r
{ /* bare King */\r
- epStatus[forwardMostMove] = EP_CHECKMATE; // make claimable as win for stm\r
+ epStatus[forwardMostMove] = EP_WINS; // 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
\r
\r
// don't wait for engine to announce game end if we can judge ourselves\r
- switch (MateTest(boards[forwardMostMove],\r
- PosFlags(forwardMostMove), epFile,\r
+ switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove), epFile,\r
castlingRights[forwardMostMove]) ) {\r
case MT_NONE:\r
case MT_CHECK:\r
default:\r
break;\r
case MT_STALEMATE:\r
- if(epStatus[forwardMostMove] != EP_CHECKMATE) // [HGM] spare win through baring or K-capt\r
- epStatus[forwardMostMove] = EP_STALEMATE;\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
- 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
+ case MT_STAINMATE:\r
+ reason = "Xboard adjudication: Stalemate";\r
+ if(epStatus[forwardMostMove] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt\r
+ epStatus[forwardMostMove] = EP_STALEMATE; // default result for stalemate is draw\r
+ if(gameInfo.variant == VariantLosers || gameInfo.variant == VariantGiveaway) // [HGM] losers:\r
+ epStatus[forwardMostMove] = EP_WINS; // in these variants stalemated is always a win\r
+ else if(gameInfo.variant == VariantSuicide) // in suicide it depends\r
+ epStatus[forwardMostMove] = NrW == NrPieces-NrW ? EP_STALEMATE :\r
+ ((NrW < NrPieces-NrW) != WhiteOnMove(forwardMostMove) ?\r
+ EP_CHECKMATE : EP_WINS);\r
+ else if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi)\r
+ epStatus[forwardMostMove] = EP_CHECKMATE; // and in these variants being stalemated loses\r
}\r
break;\r
case MT_CHECKMATE:\r
- epStatus[forwardMostMove] = EP_CHECKMATE;\r
- if(appData.checkMates) {\r
+ reason = "Xboard adjudication: Checkmate";\r
+ epStatus[forwardMostMove] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);\r
+ break;\r
+ }\r
+\r
+ switch(i = epStatus[forwardMostMove]) {\r
+ case EP_STALEMATE:\r
+ result = GameIsDrawn; break;\r
+ case EP_CHECKMATE:\r
+ result = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins; break;\r
+ case EP_WINS:\r
+ result = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins; break;\r
+ default:\r
+ result = (ChessMove) 0;\r
+ }\r
+ if(appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested\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) != (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
+ GameEnds( result, reason, GE_XBOARD );\r
return;\r
}\r
- break;\r
- }\r
\r
/* Next absolutely insufficient mating material. */\r
if( NrPieces == 2 || gameInfo.variant != VariantXiangqi && \r
if(!ourPerpetual && !hisPerpetual) { // no perpetual check, test for chase\r
hisPerpetual = PerpetualChase(k, forwardMostMove);\r
ourPerpetual = PerpetualChase(k+1, forwardMostMove);\r
- if(ourPerpetual && !hisPerpetual) { // we are actively checking him: forfeit\r
+ if(ourPerpetual && !hisPerpetual) { // we are actively chasing him: forfeit\r
GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, \r
"Xboard adjudication: perpetual chasing", GE_XBOARD );\r
return;\r
strcat(parseList[boardIndex - 1], "+");\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
strcat(parseList[boardIndex - 1], "#");\r
break;\r
}\r
strcat(parseList[forwardMostMove - 1], "+");\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
strcat(parseList[forwardMostMove - 1], "#");\r
break;\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
+ trueResult = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins;\r
+ } else\r
+ if(epStatus[forwardMostMove] == EP_WINS) { // added code for games where being mated is a win\r
+ /* [HGM] verify: engine mate claims accepted if they were flagged */\r
+ trueResult = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins;\r
} else\r
- if(epStatus[forwardMostMove] == EP_STALEMATE) {\r
+ if(epStatus[forwardMostMove] == EP_STALEMATE) { // only used to indicate draws now\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
\r
// now verify win claims, but not in drop games, as we don't understand those yet\r
case MT_CHECK:\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
if (WhiteOnMove(currentMove)) {\r
GameEnds(BlackWins, "Black mates", GE_FILE);\r
} else {\r
case MT_CHECK:\r
break;\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
if (WhiteOnMove(currentMove)) {\r
GameEnds(BlackWins, "Black mates", GE_FILE);\r
} else {\r
break;\r
\r
case MT_CHECKMATE:\r
+ case MT_STAINMATE:\r
if (WhiteOnMove(currentMove)) {\r
GameEnds(BlackWins, "Black mates", GE_PLAYER);\r
} else {\r