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
\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
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
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
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
\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
}\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
}\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
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