Implement -autoCopyPV
[xboard.git] / backend.c
index c196662..06c3145 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -734,8 +734,12 @@ ClearOptions (ChessProgramState *cps)
 }
 
 char *engineNames[] = {
-"first",
-"second"
+  /* TRANSLATORS: "first" is the first of possible two chess engines. It is inserted into strings
+     such as "%s engine" / "%s chess program" / "%s machine" - all meaning the same thing */
+N_("first"),
+  /* TRANSLATORS: "second" is the second of possible two chess engines. It is inserted into strings
+     such as "%s engine" / "%s chess program" / "%s machine" - all meaning the same thing */
+N_("second")
 };
 
 void
@@ -744,7 +748,7 @@ InitEngine (ChessProgramState *cps, int n)
 
     ClearOptions(cps);
 
-    cps->which = engineNames[n];
+    cps->which = _(engineNames[n]);
     cps->maybeThinking = FALSE;
     cps->pr = NoProc;
     cps->isr = NULL;
@@ -1242,11 +1246,9 @@ GetTimeQuota (int movenr, int lastUsed, char *tcString)
     char *s = tcString;
 
     if(!*s) return 0; // empty TC string means we ran out of the last sudden-death version
-    if(appData.debugMode) fprintf(debugFP, "TC string = '%s'\n", tcString);
     do {
         if(moves) NextSessionFromString(&s, &moves, &time, &increment, &incType);
         nextSession = s; suddenDeath = moves == 0 && increment == 0;
-        if(appData.debugMode) fprintf(debugFP, "mps=%d tc=%d inc=%d\n", moves, (int) time, (int) increment);
         if(movenr == -1) return time;    /* last move before new session     */
         if(incType == '*') increment = 0; else // for sandclock, time is added while not thinking
         if(incType == '!' && lastUsed < increment) increment = lastUsed;
@@ -1426,7 +1428,7 @@ ReserveGame (int gameNr, char resChar)
        UnloadEngine(&first);  // next game belongs to other pairing;
        UnloadEngine(&second); // already unload the engines, so TwoMachinesEvent will load new ones.
     }
-    if(appData.debugMode) fprintf(debugFP, "Reserved, next=%d, nr=%d, procs=(%x,%x)\n", nextGame, gameNr, first.pr, second.pr);
+    if(appData.debugMode) fprintf(debugFP, "Reserved, next=%d, nr=%d\n", nextGame, gameNr);
 }
 
 void
@@ -5331,9 +5333,6 @@ ParsePV (char *pv, Boolean storeComments, Boolean atEnd)
     if(nr == 0 && !storeComments && *pv == '(') pv++; // first (ponder) move can be in parentheses
     lastParseAttempt = pv;
     valid = ParseOneMove(pv, endPV, &moveType, &fromX, &fromY, &toX, &toY, &promoChar);
-if(appData.debugMode){
-fprintf(debugFP,"parsePV: %d %c%c%c%c yy='%s'\nPV = '%s'\n", valid, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, yy_textstr, pv);
-}
     if(!valid && nr == 0 &&
        ParseOneMove(pv, endPV-1, &moveType, &fromX, &fromY, &toX, &toY, &promoChar)){
         nr++; moveType = Comment; // First move has been played; kludge to make sure we continue
@@ -5452,6 +5451,7 @@ UnLoadPV ()
 {
   int oldFMM = forwardMostMove; // N.B.: this was currentMove before PV was loaded!
   if(endPV < 0) return;
+  if(appData.autoCopyPV) CopyFENToClipboard();
   endPV = -1;
   if(gameMode == AnalyzeMode && currentMove > forwardMostMove) {
        Boolean saveAnimate = appData.animate;
@@ -7563,14 +7563,6 @@ Adjudicate (ChessProgramState *cps)
                      }
                 } 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]);
-
-       }
 
        // Repetition draws and 50-move rule can be applied independently of legality testing
 
@@ -7906,11 +7898,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            return;
        }
 
-    if (appData.debugMode) { int f = forwardMostMove;
-        fprintf(debugFP, "machine move %d, castling = %d %d %d %d %d %d\n", f,
-                boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2],
-                boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]);
-    }
         if(cps->alphaRank) AlphaRank(machineMove, 4);
         if (!ParseOneMove(machineMove, forwardMostMove, &moveType,
                               &fromX, &fromY, &toX, &toY, &promoChar)) {
@@ -7936,12 +7923,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            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) {
              snprintf(buf1, MSG_SIZ*10, "Xboard: Forfeit due to illegal move: %s (%c%c%c%c)%c",
                         machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, 0);
@@ -9460,9 +9441,6 @@ MakeMove (int fromX, int fromY, int toX, int toY, int promoChar)
        strcat(parseList[forwardMostMove - 1], "#");
        break;
     }
-    if (appData.debugMode) {
-        fprintf(debugFP, "move: %s, parse: %s (%c)\n", moveList[forwardMostMove-1], parseList[forwardMostMove-1], moveList[forwardMostMove-1][4]);
-    }
 
 }
 
@@ -10071,11 +10049,11 @@ NextTourneyGame (int nr, int *swapColors)
        matchGame = 1; roundNr = nr / syncInterval + 1;
     }
 
-    if(first.pr != NoProc && second.pr != NoProc) return 1; // engines already loaded
+    if(first.pr != NoProc && second.pr != NoProc || nr<0) return 1; // engines already loaded
 
     // redefine engines, engine dir, etc.
     NamesToList(firstChessProgramNames, command, mnemonic, "all"); // get mnemonics of installed engines
-    if(first.pr == NoProc || nr < 0) {
+    if(first.pr == NoProc) {
       SetPlayer(whitePlayer, appData.participants); // find white player amongst it, and parse its engine line
       InitEngine(&first, 0);  // initialize ChessProgramStates based on new settings.
     }
@@ -10095,6 +10073,18 @@ NextMatchGame ()
 {   // performs game initialization that does not invoke engines, and then tries to start the game
     int res, firstWhite, swapColors = 0;
     if(!NextTourneyGame(nextGame, &swapColors)) return; // this sets matchGame, -fcp / -scp and other options for next game, if needed
+    if(matchMode && appData.debugMode) { // [HGM] debug split: game is part of a match; we might have to create a debug file just for this game
+       char buf[MSG_SIZ];
+       snprintf(buf, MSG_SIZ, appData.nameOfDebugFile, nextGame+1); // expand name of debug file with %d in it
+       if(strcmp(buf, currentDebugFile)) { // name has changed
+           FILE *f = fopen(buf, "w");
+           if(f) { // if opening the new file failed, just keep using the old one
+               ASSIGN(currentDebugFile, buf);
+               fclose(debugFP);
+               debugFP = f;
+           }
+       }
+    }
     firstWhite = appData.firstPlaysBlack ^ (matchGame & 1 | appData.sameColorGames > 1); // non-incremental default
     firstWhite ^= swapColors; // reverses if NextTourneyGame says we are in an odd round
     first.twoMachinesColor =  firstWhite ? "white\n" : "black\n";   // perform actual color assignement
@@ -13408,17 +13398,6 @@ TwoMachinesEvent P((void))
        break;
     }
 
-    if(matchMode && appData.debugMode) { // [HGM] debug split: game is part of a match; we might have to create a debug file just for this game
-       snprintf(buf, MSG_SIZ, appData.nameOfDebugFile, nextGame+1); // expand name of debug file with %d in it
-       if(strcmp(buf, currentDebugFile)) { // name has changed
-           FILE *f = fopen(buf, "w");
-           if(f) { // if opening the new file failed, just keep using the old one
-               ASSIGN(currentDebugFile, buf);
-               fclose(debugFP);
-               debugFP = f;
-           }
-       }
-    }
 //    forwardMostMove = currentMove;
     TruncateGame(); // [HGM] vari: MachineWhite and MachineBlack do this...
 
@@ -13932,6 +13911,8 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y)
             } else
            boards[0][y][x] = selection;
            DrawPosition(TRUE, boards[0]);
+           ClearHighlights();
+           fromX = fromY = -1;
        }
        break;
     }
@@ -14228,7 +14209,7 @@ StopExaminingEvent ()
 void
 ForwardInner (int target)
 {
-    int limit;
+    int limit; int oldSeekGraphUp = seekGraphUp;
 
     if (appData.debugMode)
        fprintf(debugFP, "ForwardInner(%d), current %d, forward %d\n",
@@ -14285,7 +14266,7 @@ ForwardInner (int target)
     }
     DisplayBothClocks();
     DisplayMove(currentMove - 1);
-    DrawPosition(FALSE, boards[currentMove]);
+    DrawPosition(oldSeekGraphUp, boards[currentMove]);
     HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1);
     if ( !matchMode && gameMode != Training) { // [HGM] PV info: routine tests if empty
        DisplayComment(currentMove - 1, commentList[currentMove]);
@@ -15251,9 +15232,6 @@ SendTimeRemaining (ChessProgramState *cps, int machineWhite)
     }
     /* [HGM] translate opponent's time by time-odds factor */
     otime = (otime * cps->other->timeOdds) / cps->timeOdds;
-    if (appData.debugMode) {
-        fprintf(debugFP, "time odds: %f %f \n", cps->timeOdds, cps->other->timeOdds);
-    }
 
     if (time <= 0) time = 1;
     if (otime <= 0) otime = 1;