X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=54a7e705d510c31c346eb90df2ff6682f7666fad;hb=f873bcd0121810783dc964c813403c10871c2cc7;hp=df586fd8016081ee49a17e05cba055d5c8c39862;hpb=9aa0bf8d13b7ad2c7763fe2807e443e730a62dcb;p=xboard.git diff --git a/backend.c b/backend.c index df586fd..54a7e70 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 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -737,8 +737,8 @@ InitBackEnd1() /* [AS] Adjudication threshold */ adjudicateLossThreshold = appData.adjudicateLossThreshold; - first.which = _("first"); - second.which = _("second"); + first.which = "first"; + second.which = "second"; first.maybeThinking = second.maybeThinking = FALSE; first.pr = second.pr = NoProc; first.isr = second.isr = NULL; @@ -2861,7 +2861,7 @@ read_from_ics(isr, closure, data, count, error) if(channel >= 0) // channel broadcast; look if there is a chatbox for this channel for(p=0; p= '0' && chatPartner[p][0] <= '9' && channel == atoi(chatPartner[p])) { talker[0] = '['; strcat(talker, "] "); Colorize(channel == 1 ? ColorChannel1 : ColorChannel, FALSE); chattingPartner = p; break; @@ -4368,7 +4368,8 @@ ParseBoard12(string) safeStrCpy(moveList[moveNum - 1], currentMoveString, sizeof(moveList[moveNum - 1])/sizeof(moveList[moveNum - 1][0])); strcat(moveList[moveNum - 1], "\n"); - if(gameInfo.holdingsWidth && !appData.disguise) // inherit info that ICS does not give from previous board + if(gameInfo.holdingsWidth && !appData.disguise && gameInfo.variant != VariantSuper + && gameInfo.variant != VariantGreat) // inherit info that ICS does not give from previous board for(k=0; k= (int) BlackPawn && (int) boards[currentMove][fromY][fromX] < (int) EmptySquare) { /* User is moving for Black */ @@ -6079,7 +6081,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar) pup = boards[currentMove][toY][toX]; /* [HGM] If move started in holdings, it means a drop. Convert to standard form */ - if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { + if( (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && fromY != DROP_RANK ) { if( pup != EmptySquare ) return; moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop; if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", @@ -6187,7 +6189,10 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar) MakeMove(fromX, fromY, toX, toY, promoChar); /*updates forwardMostMove*/ - if(Adjudicate(NULL)) return 1; // [HGM] adjudicate: take care of automtic game end + if(Adjudicate(NULL)) { // [HGM] adjudicate: take care of automatic game end + ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ + return 1; + } if (gameMode == BeginningOfGame) { if (appData.noChessProgram) { @@ -6242,6 +6247,7 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar) switch (gameMode) { case EditGame: + if(appData.testLegality) switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) { case MT_NONE: case MT_CHECK: @@ -6810,7 +6816,6 @@ Adjudicate(ChessProgramState *cps) if(canAdjudicate && appData.checkMates) { if(engineOpponent) SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins, "Xboard adjudication: King destroyed", GE_XBOARD ); return 1; @@ -6824,7 +6829,6 @@ Adjudicate(ChessProgramState *cps) if(canAdjudicate && appData.checkMates) { if(engineOpponent) SendMoveToProgram(forwardMostMove-1, engineOpponent); // 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 1; @@ -6837,7 +6841,6 @@ Adjudicate(ChessProgramState *cps) /* but only adjudicate if adjudication enabled */ if(engineOpponent) SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( nrW > 1 ? WhiteWins : nrB > 1 ? BlackWins : GameIsDrawn, "Xboard adjudication: Bare king", GE_XBOARD ); return 1; @@ -6898,7 +6901,6 @@ Adjudicate(ChessProgramState *cps) if(canAdjudicate && appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested if(engineOpponent) SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( result, reason, GE_XBOARD ); return 1; } @@ -6917,7 +6919,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see last move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( GameIsDrawn, "Xboard adjudication: Insufficient mating material", GE_XBOARD ); return 1; } @@ -6938,7 +6939,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( GameIsDrawn, "Xboard adjudication: Trivial draw", GE_XBOARD ); return 1; } @@ -7021,7 +7021,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( result, details, GE_XBOARD ); return 1; } @@ -7058,7 +7057,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( GameIsDrawn, "Xboard adjudication: 50-move rule", GE_XBOARD ); return 1; } @@ -7081,7 +7079,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( GameIsDrawn, p, GE_XBOARD ); return 1; } @@ -7092,7 +7089,6 @@ Adjudicate(ChessProgramState *cps) SendToProgram("force\n", engineOpponent); // suppress reply SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */ } - ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ GameEnds( GameIsDrawn, "Xboard adjudication: long game", GE_XBOARD ); return 1; } @@ -7271,7 +7267,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h &fromX, &fromY, &toX, &toY, &promoChar)) { /* Machine move could not be parsed; ignore it. */ snprintf(buf1, MSG_SIZ*10, _("Illegal move \"%s\" from %s machine"), - machineMove, cps->which); + machineMove, _(cps->which)); DisplayError(buf1, 0); snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to invalid move: %s (%c%c%c%c) res=%d", machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, moveType); @@ -7328,11 +7324,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if (cps->sendTime == 2) cps->sendTime = 1; if (cps->offeredDraw) cps->offeredDraw--; - /* currentMoveString is set as a side-effect of ParseOneMove */ - safeStrCpy(machineMove, currentMoveString, sizeof(machineMove)/sizeof(machineMove[0])); - strcat(machineMove, "\n"); - safeStrCpy(moveList[forwardMostMove], machineMove, sizeof(moveList[forwardMostMove])/sizeof(moveList[forwardMostMove][0])); - /* [AS] Save move info*/ pvInfoList[ forwardMostMove ].score = programStats.score; pvInfoList[ forwardMostMove ].depth = programStats.depth; @@ -7369,7 +7360,10 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h } } - if(Adjudicate(cps)) return; // [HGM] adjudicate: for all automatic game ends + if(Adjudicate(cps)) { + ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/ + return; // [HGM] adjudicate: for all automatic game ends + } #if ZIPPY if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) && @@ -7703,7 +7697,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. SwitchClocks(forwardMostMove-1); // [HGM] race DisplayBothClocks(); snprintf(buf1, 10*MSG_SIZ, _("Illegal move \"%s\" (rejected by %s chess program)"), - parseList[currentMove], cps->which); + parseList[currentMove], _(cps->which)); DisplayMoveError(buf1); DrawPosition(FALSE, boards[currentMove]); return; @@ -7728,7 +7722,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. cps->maybeThinking = FALSE; snprintf(buf1, sizeof(buf1), _("Failed to start %s chess program %s on %s: %s\n"), - cps->which, cps->program, cps->host, message); + _(cps->which), cps->program, cps->host, message); RemoveInputSource(cps->isr); DisplayFatalError(buf1, 0, 1); return; @@ -7751,7 +7745,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. /* Hint move could not be parsed!? */ snprintf(buf2, sizeof(buf2), _("Illegal hint move \"%s\"\nfrom %s chess program"), - buf1, cps->which); + buf1, _(cps->which)); DisplayError(buf2, 0); } } else { @@ -8418,7 +8412,8 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) int i; if( board[fromY][fromX] == WhiteLance || board[fromY][fromX] == BlackLance ) { - if( gameInfo.variant == VariantFairy ) board[EP_STATUS] = EP_PAWN_MOVE; // Lance in fairy is Pawn-like + if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi ) + board[EP_STATUS] = EP_PAWN_MOVE; // Lance is Pawn-like in most variants } else if( board[fromY][fromX] == WhitePawn ) { if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers @@ -8901,7 +8896,7 @@ InitChessProgram(cps, setup) if( gameInfo.variant == VariantBughouse || gameInfo.variant == VariantCrazyhouse ) overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 5; if( gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantCapaRandom || - gameInfo.variant == VariantGothic || gameInfo.variant == VariantFalcon ) + gameInfo.variant == VariantGothic || gameInfo.variant == VariantFalcon || gameInfo.variant == VariantJanus ) overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; if( gameInfo.variant == VariantCourier ) overruled = gameInfo.boardWidth != 12 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; @@ -9923,8 +9918,6 @@ LoadGameOneMove(readAhead) return FALSE; } else { /* currentMoveString is set as a side-effect of yylex */ - strcat(currentMoveString, "\n"); - safeStrCpy(moveList[forwardMostMove], currentMoveString, sizeof(moveList[forwardMostMove])/sizeof(moveList[forwardMostMove][0])); thinkOutput[0] = NULLCHAR; MakeMove(fromX, fromY, toX, toY, promoChar); @@ -10429,6 +10422,7 @@ LoadGame(f, gameNumber, title, useList) for (i = BOARD_HEIGHT - 1; i >= 0; i--) for (j = BOARD_LEFT; j < BOARD_RGHT; p++) switch (*p) { + case '{': case '[': case '-': case ' ': @@ -12616,6 +12610,30 @@ CallFlagEvent() } void +ClockClick(int which) +{ // [HGM] code moved to back-end from winboard.c + if(which) { // black clock + if (gameMode == EditPosition || gameMode == IcsExamining) { + SetBlackToPlayEvent(); + } else if (gameMode == EditGame || shiftKey) { + AdjustClock(which, -1); + } else if (gameMode == IcsPlayingWhite || + gameMode == MachinePlaysBlack) { + CallFlagEvent(); + } + } else { // white clock + if (gameMode == EditPosition || gameMode == IcsExamining) { + SetWhiteToPlayEvent(); + } else if (gameMode == EditGame || shiftKey) { + AdjustClock(which, -1); + } else if (gameMode == IcsPlayingBlack || + gameMode == MachinePlaysWhite) { + CallFlagEvent(); + } + } +} + +void DrawEvent() { /* Offer draw or accept pending draw offer from opponent */ @@ -13550,11 +13568,11 @@ SendToProgram(message, cps) outCount = OutputToProcess(cps->pr, message, count, &error); if (outCount < count && !exiting && !endingGame) { /* [HGM] crash: to not hang GameEnds() writing to deceased engines */ - snprintf(buf, MSG_SIZ, _("Error writing to %s chess program"), cps->which); + snprintf(buf, MSG_SIZ, _("Error writing to %s chess program"), _(cps->which)); if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */ if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) { gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */ - snprintf(buf, MSG_SIZ, "%s program exits in draw position (%s)", cps->which, cps->program); + snprintf(buf, MSG_SIZ, _("%s program exits in draw position (%s)"), _(cps->which), cps->program); } else { gameInfo.result = cps->twoMachinesColor[0]=='w' ? BlackWins : WhiteWins; } @@ -13580,11 +13598,11 @@ ReceiveFromProgram(isr, closure, message, count, error) if (count <= 0) { if (count == 0) { snprintf(buf, MSG_SIZ, _("Error: %s chess program (%s) exited unexpectedly"), - cps->which, cps->program); + _(cps->which), cps->program); if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */ if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) { gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */ - snprintf(buf, MSG_SIZ, _("%s program exits in draw position (%s)"), cps->which, cps->program); + snprintf(buf, MSG_SIZ, _("%s program exits in draw position (%s)"), _(cps->which), cps->program); } else { gameInfo.result = cps->twoMachinesColor[0]=='w' ? BlackWins : WhiteWins; } @@ -13594,7 +13612,7 @@ ReceiveFromProgram(isr, closure, message, count, error) if(!cps->userError || !appData.popupExitMessage) DisplayFatalError(buf, 0, 1); else errorExitStatus = 1; } else { snprintf(buf, MSG_SIZ, _("Error reading from %s chess program (%s)"), - cps->which, cps->program); + _(cps->which), cps->program); RemoveInputSource(cps->isr); /* [AS] Program is misbehaving badly... kill it */ @@ -13712,7 +13730,7 @@ SendTimeControl(cps, mps, tc, inc, sd, st) SendToProgram(buf, cps); } - if(cps->nps > 0) { /* [HGM] nps */ + if(cps->nps >= 0) { /* [HGM] nps */ if(cps->supportsNPS == FALSE) cps->nps = -1; // don't use if engine explicitly says not supported! else { @@ -14005,7 +14023,7 @@ ParseFeatures(args, cps) } if(cps->nrOptions >= MAX_OPTIONS) { cps->nrOptions--; - snprintf(buf, MSG_SIZ, "%s engine has too many options\n", cps->which); + snprintf(buf, MSG_SIZ, _("%s engine has too many options\n"), _(cps->which)); DisplayError(buf, 0); } continue; @@ -14541,15 +14559,15 @@ SwitchClocks(int newMoveNr) if(blackNPS >= 0) lastTickLength = 0; blackTimeRemaining -= lastTickLength; /* [HGM] PGNtime: save time for PGN file if engine did not give it */ -// if(pvInfoList[forwardMostMove-1].time == -1) - pvInfoList[forwardMostMove-1].time = // use GUI time +// if(pvInfoList[forwardMostMove].time == -1) + pvInfoList[forwardMostMove].time = // use GUI time (timeRemaining[1][forwardMostMove-1] - blackTimeRemaining)/10; } else { if(whiteNPS >= 0) lastTickLength = 0; whiteTimeRemaining -= lastTickLength; /* [HGM] PGNtime: save time for PGN file if engine did not give it */ -// if(pvInfoList[forwardMostMove-1].time == -1) - pvInfoList[forwardMostMove-1].time = +// if(pvInfoList[forwardMostMove].time == -1) + pvInfoList[forwardMostMove].time = (timeRemaining[0][forwardMostMove-1] - whiteTimeRemaining)/10; } flagged = CheckFlags();