if (gameMode == TwoMachinesPlay) {
GameEnds(machineWhite ? BlackWins : WhiteWins,
buf1, GE_XBOARD);
-<<<<<<< HEAD
}
return;
}
if (cps->sendTime == 2) cps->sendTime = 1;
if (cps->offeredDraw) cps->offeredDraw--;
-#if ZIPPY
- if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) &&
- first.initDone) {
- SendMoveToICS(moveType, fromX, fromY, toX, toY);
- ics_user_moved = 1;
- if(appData.autoKibitz && !appData.icsEngineAnalyze ) { /* [HGM] kibitz: send most-recent PV info to ICS */
- char buf[3*MSG_SIZ];
-
- sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %u nodes, %.0f knps) PV=%s\n",
- programStats.score / 100.,
- programStats.depth,
- programStats.time / 100.,
- (unsigned int)programStats.nodes,
- (unsigned int)programStats.nodes / (10*abs(programStats.time) + 1.),
- programStats.movelist);
- SendToICS(buf);
-if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.nodes, programStats.nodes);
- }
- }
-#endif
/* currentMoveString is set as a side-effect of ParseOneMove */
strcpy(machineMove, currentMoveString);
strcat(machineMove, "\n");
strcpy(moveList[forwardMostMove], machineMove);
- /* [AS] Save move info and clear stats for next move */
- pvInfoList[ forwardMostMove ].score = programStats.score;
- pvInfoList[ forwardMostMove ].depth = programStats.depth;
- pvInfoList[ forwardMostMove ].time = programStats.time; // [HGM] PGNtime: take time from engine stats
- ClearProgramStats();
- thinkOutput[0] = NULLCHAR;
- hiddenThinkOutputState = 0;
-
MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
/* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */
if( count >= adjudicateLossPlies ) {
ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
- "Xboard adjudication",
- GE_XBOARD );
-
- return;
- }
- }
-
- if( gameMode == TwoMachinesPlay ) {
- // [HGM] some adjudications useful with buggy engines
- int k, count = 0; static int bare = 1;
- if(gameInfo.holdingsSize == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
-
-
- if( appData.testLegality )
- { /* [HGM] Some more adjudications for obstinate engines */
- int NrWN=0, NrBN=0, NrWB=0, NrBB=0, NrWR=0, NrBR=0,
- NrWQ=0, NrBQ=0, NrW=0, NrK=0, bishopsColor = 0,
- NrPieces=0, NrPawns=0, PawnAdvance=0, i, j;
- static int moveCount = 6;
- ChessMove result;
- char *reason = NULL;
-
- /* Count what is on board. */
- for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++)
- { ChessSquare p = boards[forwardMostMove][i][j];
- int m=i;
-
- switch((int) p)
- { /* count B,N,R and other of each side */
- case WhiteKing:
- case BlackKing:
- NrK++; break; // [HGM] atomic: count Kings
- case WhiteKnight:
- NrWN++; break;
- case WhiteBishop:
- case WhiteFerz: // [HGM] shatranj: kludge to mke it work in shatranj
- bishopsColor |= 1 << ((i^j)&1);
- NrWB++; break;
- case BlackKnight:
- NrBN++; break;
- case BlackBishop:
- case BlackFerz: // [HGM] shatranj: kludge to mke it work in shatranj
- bishopsColor |= 1 << ((i^j)&1);
- NrBB++; break;
- case WhiteRook:
- NrWR++; break;
- case BlackRook:
- NrBR++; break;
- case WhiteQueen:
- NrWQ++; break;
- case BlackQueen:
- NrBQ++; break;
- case EmptySquare:
- break;
- case BlackPawn:
- m = 7-i;
- case WhitePawn:
- PawnAdvance += m; NrPawns++;
- }
- NrPieces += (p != EmptySquare);
- NrW += ((int)p < (int)BlackPawn);
- if(gameInfo.variant == VariantXiangqi &&
- (p == WhiteFerz || p == WhiteAlfil || p == BlackFerz || p == BlackAlfil)) {
- NrPieces--; // [HGM] XQ: do not count purely defensive pieces
- NrW -= ((int)p < (int)BlackPawn);
- }
- }
-
- /* Some material-based adjudications that have to be made before stalemate test */
- if(gameInfo.variant == VariantAtomic && NrK < 2) {
- // [HGM] atomic: stm must have lost his King on previous move, as destroying own K is illegal
- boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // make claimable as if stm is checkmated
- if(appData.checkMates) {
- SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins,
- "Xboard adjudication: King destroyed", GE_XBOARD );
- return;
- }
- }
-
- /* Bare King in Shatranj (loses) or Losers (wins) */
- if( NrW == 1 || NrPieces - NrW == 1) {
- if( gameInfo.variant == VariantLosers) { // [HGM] losers: bare King wins (stm must have it first)
- boards[forwardMostMove][EP_STATUS] = EP_WINS; // mark as win, so it becomes claimable
- if(appData.checkMates) {
- SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets to see move
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
- "Xboard adjudication: Bare king", GE_XBOARD );
- return;
- }
- } else
- if( gameInfo.variant == VariantShatranj && --bare < 0)
- { /* bare King */
- boards[forwardMostMove][EP_STATUS] = EP_WINS; // make claimable as win for stm
- if(appData.checkMates) {
- /* but only adjudicate if adjudication enabled */
- SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( NrW > 1 ? WhiteWins : NrPieces - NrW > 1 ? BlackWins : GameIsDrawn,
- "Xboard adjudication: Bare king", GE_XBOARD );
- return;
- }
- }
- } else bare = 1;
-
-
- // don't wait for engine to announce game end if we can judge ourselves
- switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
- case MT_CHECK:
- if(gameInfo.variant == Variant3Check) { // [HGM] 3check: when in check, test if 3rd time
- int i, checkCnt = 0; // (should really be done by making nr of checks part of game state)
- for(i=forwardMostMove-2; i>=backwardMostMove; i-=2) {
- if(MateTest(boards[i], PosFlags(i)) == MT_CHECK)
- checkCnt++;
- if(checkCnt >= 2) {
- reason = "Xboard adjudication: 3rd check";
- boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE;
- break;
- }
- }
- }
- case MT_NONE:
- default:
- break;
- case MT_STALEMATE:
- case MT_STAINMATE:
- reason = "Xboard adjudication: Stalemate";
- if((signed char)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
- boards[forwardMostMove][EP_STATUS] = EP_STALEMATE; // default result for stalemate is draw
- if(gameInfo.variant == VariantLosers || gameInfo.variant == VariantGiveaway) // [HGM] losers:
- boards[forwardMostMove][EP_STATUS] = EP_WINS; // in these variants stalemated is always a win
- else if(gameInfo.variant == VariantSuicide) // in suicide it depends
- boards[forwardMostMove][EP_STATUS] = NrW == NrPieces-NrW ? EP_STALEMATE :
- ((NrW < NrPieces-NrW) != WhiteOnMove(forwardMostMove) ?
- EP_CHECKMATE : EP_WINS);
- else if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi)
- boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // and in these variants being stalemated loses
- }
- break;
- case MT_CHECKMATE:
- reason = "Xboard adjudication: Checkmate";
- boards[forwardMostMove][EP_STATUS] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);
- break;
-=======
->>>>>>> master
- }
- return;
- }
-
-<<<<<<< HEAD
- switch(i = (signed char)boards[forwardMostMove][EP_STATUS]) {
- case EP_STALEMATE:
- result = GameIsDrawn; break;
- case EP_CHECKMATE:
- result = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins; break;
- case EP_WINS:
- result = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins; break;
- default:
- result = (ChessMove) 0;
- }
- if(appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested
- SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( result, reason, GE_XBOARD );
- return;
- }
-
- /* Next absolutely insufficient mating material. */
- if( NrPieces == 2 || gameInfo.variant != VariantXiangqi &&
- gameInfo.variant != VariantShatranj && // [HGM] baring will remain possible
- (NrPieces == 3 && NrWN+NrBN+NrWB+NrBB == 1 ||
- NrPieces == NrBB+NrWB+2 && bishopsColor != 3)) // [HGM] all Bishops (Ferz!) same color
- { /* KBK, KNK, KK of KBKB with like Bishops */
-=======
- /* [HGM] Apparently legal, but so far only tested with EP_UNKOWN */
- /* So we have to redo legality test with true e.p. status here, */
- /* to make sure an illegal e.p. capture does not slip through, */
- /* to cause a forfeit on a justified illegal-move complaint */
- /* of the opponent. */
- if( gameMode==TwoMachinesPlay && appData.testLegality
- && fromY != DROP_RANK /* [HGM] temporary; should still add legality test for drops */
- ) {
- ChessMove moveType;
- moveType = LegalityTest(boards[forwardMostMove], PosFlags(forwardMostMove),
- fromY, fromX, toY, toX, promoChar);
- if (appData.debugMode) {
- int i;
- for(i=0; i< nrCastlingRights; i++) fprintf(debugFP, "(%d,%d) ",
- boards[forwardMostMove][CASTLING][i], castlingRank[i]);
- fprintf(debugFP, "castling rights\n");
- }
- if(moveType == IllegalMove) {
- sprintf(buf1, "Xboard: Forfeit due to illegal move: %s (%c%c%c%c)%c",
- machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, 0);
- GameEnds(machineWhite ? BlackWins : WhiteWins,
- buf1, GE_XBOARD);
- return;
- } else if(gameInfo.variant != VariantFischeRandom && gameInfo.variant != VariantCapaRandom)
- /* [HGM] Kludge to handle engines that send FRC-style castling
- when they shouldn't (like TSCP-Gothic) */
- switch(moveType) {
- case WhiteASideCastleFR:
- case BlackASideCastleFR:
- toX+=2;
- currentMoveString[2]++;
- break;
- case WhiteHSideCastleFR:
- case BlackHSideCastleFR:
- toX--;
- currentMoveString[2]--;
- break;
- default: ; // nothing to do, but suppresses warning of pedantic compilers
- }
- }
- hintRequested = FALSE;
- lastHint[0] = NULLCHAR;
- bookRequested = FALSE;
- /* Program may be pondering now */
- cps->maybeThinking = TRUE;
- if (cps->sendTime == 2) cps->sendTime = 1;
- if (cps->offeredDraw) cps->offeredDraw--;
->>>>>>> master
-
- /* currentMoveString is set as a side-effect of ParseOneMove */
- strcpy(machineMove, currentMoveString);
- strcat(machineMove, "\n");
- strcpy(moveList[forwardMostMove], machineMove);
-
- MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
-
-<<<<<<< HEAD
- /* Then some trivial draws (only adjudicate, cannot be claimed) */
- if(NrPieces == 4 &&
- ( NrWR == 1 && NrBR == 1 /* KRKR */
- || NrWQ==1 && NrBQ==1 /* KQKQ */
- || NrWN==2 || NrBN==2 /* KNNK */
- || NrWN+NrWB == 1 && NrBN+NrBB == 1 /* KBKN, KBKB, KNKN */
- ) ) {
- if(--moveCount < 0 && appData.trivialDraws)
- { /* if the first 3 moves do not show a tactical win, declare draw */
- SendToProgram("force\n", cps->other); // suppress reply
- SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( GameIsDrawn, "Xboard adjudication: Trivial draw", GE_XBOARD );
- return;
- }
- } else moveCount = 6;
- }
- }
-
- if (appData.debugMode) { int i;
- fprintf(debugFP, "repeat test fmm=%d bmm=%d ep=%d, reps=%d\n",
- forwardMostMove, backwardMostMove, boards[backwardMostMove][EP_STATUS],
- appData.drawRepeats);
- for( i=forwardMostMove; i>=backwardMostMove; i-- )
- fprintf(debugFP, "%d ep=%d\n", i, (signed char)boards[i][EP_STATUS]);
-
- }
-
- /* Check for rep-draws */
- count = 0;
- for(k = forwardMostMove-2;
- k>=backwardMostMove && k>=forwardMostMove-100 &&
- (signed char)boards[k][EP_STATUS] < EP_UNKNOWN &&
- (signed char)boards[k+2][EP_STATUS] <= EP_NONE && (signed char)boards[k+1][EP_STATUS] <= EP_NONE;
- k-=2)
- { int rights=0;
- if(CompareBoards(boards[k], boards[forwardMostMove])) {
- /* compare castling rights */
- if( boards[forwardMostMove][CASTLING][2] != boards[k][CASTLING][2] &&
- (boards[k][CASTLING][0] != NoRights || boards[k][CASTLING][1] != NoRights) )
- rights++; /* King lost rights, while rook still had them */
- if( boards[forwardMostMove][CASTLING][2] != NoRights ) { /* king has rights */
- if( boards[forwardMostMove][CASTLING][0] != boards[k][CASTLING][0] ||
- boards[forwardMostMove][CASTLING][1] != boards[k][CASTLING][1] )
- rights++; /* but at least one rook lost them */
- }
- if( boards[forwardMostMove][CASTLING][5] != boards[k][CASTLING][5] &&
- (boards[k][CASTLING][3] != NoRights || boards[k][CASTLING][4] != NoRights) )
- rights++;
- if( boards[forwardMostMove][CASTLING][5] != NoRights ) {
- if( boards[forwardMostMove][CASTLING][3] != boards[k][CASTLING][3] ||
- boards[forwardMostMove][CASTLING][4] != boards[k][CASTLING][4] )
- rights++;
- }
- if( rights == 0 && ++count > appData.drawRepeats-2
- && appData.drawRepeats > 1) {
- /* adjudicate after user-specified nr of repeats */
- SendToProgram("force\n", cps->other); // suppress reply
- SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- if(gameInfo.variant == VariantXiangqi && appData.testLegality) {
- // [HGM] xiangqi: check for forbidden perpetuals
- int m, ourPerpetual = 1, hisPerpetual = 1;
- for(m=forwardMostMove; m>k; m-=2) {
- if(MateTest(boards[m], PosFlags(m)) != MT_CHECK)
- ourPerpetual = 0; // the current mover did not always check
- if(MateTest(boards[m-1], PosFlags(m-1)) != MT_CHECK)
- hisPerpetual = 0; // the opponent did not always check
- }
- if(appData.debugMode) fprintf(debugFP, "XQ perpetual test, our=%d, his=%d\n",
- ourPerpetual, hisPerpetual);
- if(ourPerpetual && !hisPerpetual) { // we are actively checking him: forfeit
- GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
- "Xboard adjudication: perpetual checking", GE_XBOARD );
- return;
- }
- if(hisPerpetual && !ourPerpetual) // he is checking us, but did not repeat yet
- break; // (or we would have caught him before). Abort repetition-checking loop.
- // Now check for perpetual chases
- if(!ourPerpetual && !hisPerpetual) { // no perpetual check, test for chase
- hisPerpetual = PerpetualChase(k, forwardMostMove);
- ourPerpetual = PerpetualChase(k+1, forwardMostMove);
- if(ourPerpetual && !hisPerpetual) { // we are actively chasing him: forfeit
- GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
- "Xboard adjudication: perpetual chasing", GE_XBOARD );
- return;
- }
- if(hisPerpetual && !ourPerpetual) // he is chasing us, but did not repeat yet
- break; // Abort repetition-checking loop.
- }
- // if neither of us is checking or chasing all the time, or both are, it is draw
- }
- GameEnds( GameIsDrawn, "Xboard adjudication: repetition draw", GE_XBOARD );
- return;
- }
- if( rights == 0 && count > 1 ) /* occurred 2 or more times before */
- boards[forwardMostMove][EP_STATUS] = EP_REP_DRAW;
- }
- }
-
- /* Now we test for 50-move draws. Determine ply count */
- count = forwardMostMove;
- /* look for last irreversble move */
- while( (signed char)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
- count--;
- /* if we hit starting position, add initial plies */
- if( count == backwardMostMove )
- count -= initialRulePlies;
- count = forwardMostMove - count;
- if( count >= 100)
- boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW;
- /* this is used to judge if draw claims are legal */
- if(appData.ruleMoves > 0 && count >= 2*appData.ruleMoves) {
- SendToProgram("force\n", cps->other); // suppress reply
- SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
- GameEnds( GameIsDrawn, "Xboard adjudication: 50-move rule", GE_XBOARD );
- return;
-=======
- /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */
- if( gameMode == TwoMachinesPlay && adjudicateLossThreshold != 0 && forwardMostMove >= adjudicateLossPlies ) {
- int count = 0;
-
- while( count < adjudicateLossPlies ) {
- int score = pvInfoList[ forwardMostMove - count - 1 ].score;
-
- if( count & 1 ) {
- score = -score; /* Flip score for winning side */
->>>>>>> master
- }
-
- if( score > adjudicateLossThreshold ) {
- break;
- }
-
- count++;
- }
-
- if( count >= adjudicateLossPlies ) {
- ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
-
GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
"Xboard adjudication",
GE_XBOARD );