void DisplayTwoMachinesTitle P(());
static void ExcludeClick P((int index));
void ToggleSecond P((void));
+void PauseEngine P((ChessProgramState *cps));
#ifdef WIN32
extern void ConsoleCreate();
Boolean valid;
int nr = 0;
- if (gameMode == AnalyzeMode && currentMove < forwardMostMove) {
+ lastParseAttempt = pv; if(!*pv) return; // turns out we crash when we parse an empty PV
+ if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) && currentMove < forwardMostMove) {
PushInner(currentMove, forwardMostMove); // [HGM] engine might not be thinking on forwardMost position!
pushed = TRUE;
}
static char buf[10*MSG_SIZ];
int i, k=0, savedEnd=endPV, saveFMM = forwardMostMove;
*buf = NULLCHAR;
- if(forwardMostMove < endPV) PushInner(forwardMostMove, endPV);
+ if(forwardMostMove < endPV) PushInner(forwardMostMove, endPV); // shelve PV of PV-walk
ParsePV(pv, FALSE, 2); // this appends PV to game, suppressing any display of it
for(i = forwardMostMove; i<endPV; i++){
if(i&1) snprintf(buf+k, 10*MSG_SIZ-k, "%s ", parseList[i]);
k += strlen(buf+k);
}
snprintf(buf+k, 10*MSG_SIZ-k, "%s", lastParseAttempt); // if we ran into stuff that could not be parsed, print it verbatim
+ if(pushed) { PopInner(0); pushed = FALSE; } // restore game continuation shelved by ParsePV
if(forwardMostMove < savedEnd) { PopInner(0); forwardMostMove = saveFMM; } // PopInner would set fmm to endPV!
endPV = savedEnd;
return buf;
return;
}
doubleClick = FALSE;
- if(gameMode == AnalyzeMode && pausing && first.excludeMoves) { // use pause state to exclude moves
+ if(gameMode == AnalyzeMode && (pausing || controlKey) && first.excludeMoves) { // use pause state to exclude moves
doubleClick = TRUE; gatingPiece = boards[currentMove][y][x];
}
fromX = x; fromY = y; toX = toY = -1;
|| majors + (12*pCnt[BlackFerz-side] | 6*pCnt[BlackAlfil-side]) > 16; // KCKAA, KCKAX, KCKEEX, KCKEXX (XX!=HH), KCKXXX
// TO DO: cases wih an unpromoted f-Pawn acting as platform for an opponent Cannon
+ } else if(v == VariantKnightmate) {
+ if(nMine == 1) return FALSE;
+ if(nMine == 2 && nHis == 1 && pCnt[WhiteBishop+side] + pCnt[WhiteFerz+side] + pCnt[WhiteKnight+side]) return FALSE; // KBK is only draw
} else if(pCnt[WhiteKing] == 1 && pCnt[BlackKing] == 1) { // other variants with orthodox Kings
int nBishops = pCnt[WhiteBishop+side] + pCnt[WhiteFerz+side];
// In any case it determnes if the game is a claimable draw (filling in EP_STATUS).
// Actually ending the game is now based on the additional internal condition canAdjudicate.
// Only when the game is ended, and the opponent is a computer, this opponent gets the move relayed.
- int k, count = 0; static int bare = 1;
+ int k, drop, count = 0; static int bare = 1;
ChessProgramState *engineOpponent = (gameMode == TwoMachinesPlay ? cps->other : (cps ? NULL : &first));
Boolean canAdjudicate = !appData.icsActive;
/* Check for rep-draws */
count = 0;
+ drop = gameInfo.holdingsSize && (gameInfo.variant != VariantSuper && gameInfo.variant != VariantSChess
+ && gameInfo.variant != VariantGreat && gameInfo.variant != VariantGrand);
for(k = forwardMostMove-2;
- k>=backwardMostMove && k>=forwardMostMove-100 &&
+ k>=backwardMostMove && k>=forwardMostMove-100 && (drop ||
(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;
+ (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])) {
if(appData.debugMode) fprintf(debugFP, "pause %s engine after move\n", cps->which);
safeStrCpy(stashedInputMove, message, MSG_SIZ);
stalledEngine = cps;
- if(appData.ponderNextMove) { // bring both engines out of ponder
- SendToProgram("easy\n", &first);
- if(gameMode == TwoMachinesPlay) SendToProgram("easy\n", &second);
+ if(appData.ponderNextMove) { // bring opponent out of ponder
+ if(gameMode == TwoMachinesPlay) {
+ if(cps->other->pause)
+ PauseEngine(cps->other);
+ else
+ SendToProgram("easy\n", cps->other);
+ }
}
StopClocks();
return;
if (oldGameMode == AnalyzeFile ||
oldGameMode == AnalyzeMode) {
appData.loadGameIndex = -1; // [HGM] order auto-stepping through games
- keepInfo = 1;
AnalyzeFileEvent();
- keepInfo = 0;
}
if(creatingBook) return TRUE;
if(stalledEngine) { // [HGM] pause: resume game by releasing withheld move
StartClocks();
if(gameMode == TwoMachinesPlay) { // we might have to make the opponent resume pondering
- if(stalledEngine->other->pause) UnPauseEngine(stalledEngine->other);
+ if(stalledEngine->other->pause == 2) UnPauseEngine(stalledEngine->other);
else if(appData.ponderNextMove) SendToProgram("hard\n", stalledEngine->other);
}
if(appData.ponderNextMove) SendToProgram("hard\n", stalledEngine);
Reset(FALSE, TRUE);
SendToICS(ics_prefix);
SendToICS("refresh\n");
- } else if (currentMove < forwardMostMove) {
+ } else if (currentMove < forwardMostMove && gameMode != AnalyzeMode) {
ForwardInner(forwardMostMove);
}
pauseExamInvalid = FALSE;
else
SendToProgram("easy\n", onMove->other);
StopClocks();
- }
+ } else if(appData.ponderNextMove) SendToProgram("easy\n", onMove); // pre-emptively bring out of ponder
} else if(gameMode == (WhiteOnMove(forwardMostMove) ? MachinePlaysWhite : MachinePlaysBlack)) { // engine on move
if(first.pause) {
PauseEngine(&first);
StopClocks();
- }
+ } else if(appData.ponderNextMove) SendToProgram("easy\n", &first); // pre-emptively bring out of ponder
} else { // human on move, pause pondering by either method
if(first.pause)
PauseEngine(&first);
- else
+ else if(appData.ponderNextMove)
SendToProgram("easy\n", &first);
StopClocks();
}
}
if (gameMode != AnalyzeMode) {
+ keepInfo = 1; // mere annotating should not alter PGN tags
EditGameEvent();
+ keepInfo = 0;
if (gameMode != EditGame) return;
if (!appData.showThinking) ToggleShowThinking();
ResurrectChessProgram();
gameMode = AnalyzeFile;
pausing = FALSE;
ModeHighlight();
- SetGameInfo();
StartAnalysisClock();
GetTimeMark(&lastNodeCountTime);