Fix bug in sending cores command to engine
[xboard.git] / backend.c
index 53799ec..bb52007 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -6266,7 +6266,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
 {
     int x, y;
     Boolean saveAnimate;
-    static int second = 0, promotionChoice = 0;
+    static int second = 0, promotionChoice = 0, dragging = 0;
     char promoChoice = NULLCHAR;
 
     if(appData.seekGraph && appData.icsActive && loggedOn &&
@@ -6326,11 +6326,14 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
                fromY = y;
                second = 0;
                MarkTargetSquares(0);
-               DragPieceBegin(xPix, yPix);
+               DragPieceBegin(xPix, yPix); dragging = 1;
                if (appData.highlightDragging) {
                    SetHighlights(x, y, -1, -1);
                }
            }
+       } else if(dragging) { // [HGM] from-square must have been reset due to game end since last press
+           DragPieceEnd(xPix, yPix); dragging = 0;
+           DrawPosition(FALSE, NULL);
        }
        return;
       }
@@ -6359,7 +6362,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
             !(fromP == BlackKing && toP == BlackRook && frc))) {
            /* Clicked again on same color piece -- changed his mind */
            second = (x == fromX && y == fromY);
-          if(!second || !OnlyMove(&x, &y, TRUE)) {
+          if(!second || appData.oneClick && !OnlyMove(&x, &y, TRUE)) {
            if (appData.highlightDragging) {
                SetHighlights(x, y, -1, -1);
            } else {
@@ -6367,7 +6370,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
            }
            if (OKToStartUserMove(x, y)) {
                fromX = x;
-               fromY = y;
+               fromY = y; dragging = 1;
                MarkTargetSquares(0);
                DragPieceBegin(xPix, yPix);
            }
@@ -6379,7 +6382,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
     }
 
     if (clickType == Release && x == fromX && y == fromY) {
-       DragPieceEnd(xPix, yPix);
+       DragPieceEnd(xPix, yPix); dragging = 0;
        if (appData.animateDragging) {
            /* Undo animation damage if any */
            DrawPosition(FALSE, NULL);
@@ -6417,7 +6420,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
        } else {
            ClearHighlights();
        }
-       DragPieceEnd(xPix, yPix);
+       DragPieceEnd(xPix, yPix); dragging = 0;
        /* Don't animate move and drag both */
        appData.animate = FALSE;
     }
@@ -6637,8 +6640,10 @@ Adjudicate(ChessProgramState *cps)
                         case BlackRook:
                              NrBR++; break;
                         case WhiteQueen:
+                        case WhiteCannon:
                              NrWQ++; break;
                         case BlackQueen:
+                        case BlackCannon:
                              NrBQ++; break;
                         case EmptySquare: 
                              break;
@@ -6760,7 +6765,10 @@ Adjudicate(ChessProgramState *cps)
                 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
+                        NrPieces == NrBB+NrWB+2 && bishopsColor != 3) // [HGM] all Bishops (Ferz!) same color
+                                 || gameInfo.variant == VariantXiangqi &&
+                       (NrPieces == 3 && (NrWQ==1 && NrWB==0 && NrBB<2 || NrBQ==1 && NrBB==0 && NrWB<2) ||
+                        NrPieces == 4 && NrWQ==1 && NrBQ==1 && NrWB==0 && NrBB==0))
                 {    /* KBK, KNK, KK of KBKB with like Bishops */
 
                      /* always flag draws, for judging claims */
@@ -6894,6 +6902,17 @@ Adjudicate(ChessProgramState *cps)
                 if( count == backwardMostMove )
                     count -= initialRulePlies;
                 count = forwardMostMove - count; 
+               if(gameInfo.variant == VariantXiangqi && ( count >= 100 || count >= 2*appData.ruleMoves ) ) {
+                       // adjust reversible move counter for checks in Xiangqi
+                       int i = forwardMostMove - count, inCheck = 0, lastCheck;
+                       if(i < backwardMostMove) i = backwardMostMove;
+                       while(i <= forwardMostMove) {
+                               lastCheck = inCheck; // check evasion does not count
+                               inCheck = (MateTest(boards[i], PosFlags(i)) == MT_CHECK);
+                               if(inCheck || lastCheck) count--; // check does not count
+                               i++;
+                       }
+               }
                 if( count >= 100)
                          boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW;
                          /* this is used to judge if draw claims are legal */
@@ -6962,8 +6981,7 @@ char *SendMoveToBookUser(int moveNr, ChessProgramState *cps, int initial)
        // after a book hit we never send 'go', and the code after the call to this routine
        // has '&& !bookHit' added to suppress potential sending there (based on 'firstMove').
        char buf[MSG_SIZ];
-       if (cps->useUsermove) sprintf(buf, "usermove "); // sorry, no SAN yet :(
-       sprintf(buf, "%s\n", bookHit); // force book move into program supposed to play it
+       sprintf(buf, "%s%s\n", (cps->useUsermove ? "usermove " : ""), bookHit); // force book move into program supposed to play it
        SendToProgram(buf, cps);
        if(!initial) firstMove = FALSE; // normally we would clear the firstMove condition after return & sending 'go'
     } else if(initial) { // 'go' was needed irrespective of firstMove, and it has to be done in this routine
@@ -7180,6 +7198,11 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
        strcat(machineMove, "\n");
        strcpy(moveList[forwardMostMove], machineMove);
 
+        /* [AS] Save move info*/
+        pvInfoList[ forwardMostMove ].score = programStats.score;
+        pvInfoList[ forwardMostMove ].depth = programStats.depth;
+        pvInfoList[ forwardMostMove ].time =  programStats.time; // [HGM] PGNtime: take time from engine stats
+
        MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
 
         /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */
@@ -7239,10 +7262,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
        }
 #endif
 
-        /* [AS] Save move info and clear stats for next move */
-        pvInfoList[ forwardMostMove-1 ].score = programStats.score;
-        pvInfoList[ forwardMostMove-1 ].depth = programStats.depth;
-        pvInfoList[ forwardMostMove-1 ].time =  programStats.time; // [HGM] PGNtime: take time from engine stats
+        /* [AS] Clear stats for next move */
         ClearProgramStats();
         thinkOutput[0] = NULLCHAR;
         hiddenThinkOutputState = 0;
@@ -8577,7 +8597,7 @@ MakeMove(fromX, fromY, toX, toY, promoChar)
         if( (boards[forwardMostMove][fromY][fromX] == WhitePawn ||
              boards[forwardMostMove][fromY][fromX] == BlackPawn   ) &&
              boards[forwardMostMove][toY][toX] == EmptySquare
-             && fromX != toX )
+             && fromX != toX && fromY != toY)
                 fprintf(serverMoves, ":%c%c:%c%c", AAA+fromX, ONE+fromY, AAA+toX, ONE+fromY);
         // promotion suffix
         if(promoChar != NULLCHAR)
@@ -10168,6 +10188,7 @@ LoadGame(f, gameNumber, title, useList)
         /* [HGM] PGNvariant: automatically switch to variant given in PGN tag */
         if(gameInfo.variant != oldVariant) {
             startedFromPositionFile = FALSE; /* [HGM] loadPos: variant switch likely makes position invalid */
+           ResetFrontEnd(); // [HGM] might need other bitmaps. Cannot use Reset() because it clears gameInfo :-(
            InitPosition(TRUE);
             oldVariant = gameInfo.variant;
            if (appData.debugMode) 
@@ -13783,7 +13804,6 @@ ParseFeatures(args, cps)
        }
        continue;
     }
-    if (BoolFeature(&p, "smp", &cps->maxCores, cps)) continue;
     /* End of additions by HGM */
 
     /* unknown feature: complain and skip */
@@ -13847,17 +13867,17 @@ PonderNextMoveEvent(newState)
 }
 
 void
-NewSettingEvent(option, command, value)
+NewSettingEvent(option, feature, command, value)
      char *command;
-     int option, value;
+     int option, value, *feature;
 {
     char buf[MSG_SIZ];
 
     if (gameMode == EditPosition) EditPositionDone(TRUE);
     sprintf(buf, "%s%s %d\n", (option ? "option ": ""), command, value);
-    SendToProgram(buf, &first);
+    if(feature == NULL || *feature) SendToProgram(buf, &first);
     if (gameMode == TwoMachinesPlay) {
-       SendToProgram(buf, &second);
+       if(feature == NULL || feature[(int*)&second - (int*)&first]) SendToProgram(buf, &second);
     }
 }