Updated copyright notice to 2011
[xboard.git] / backend.c
index cd53ac6..6eba7f6 100644 (file)
--- 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
  *
@@ -5303,8 +5303,8 @@ InitPosition(redraw)
     int i, j, pawnRow, overrule,
     oldx = gameInfo.boardWidth,
     oldy = gameInfo.boardHeight,
-    oldh = gameInfo.holdingsWidth,
-    oldv = gameInfo.variant;
+    oldh = gameInfo.holdingsWidth;
+    static int oldv;
 
     if(appData.icsActive) shuffleOpenings = FALSE; // [HGM] shuffle: in ICS mode, only shuffle on ICS request
 
@@ -5566,18 +5566,12 @@ InitPosition(redraw)
 
     if(oldx != gameInfo.boardWidth ||
        oldy != gameInfo.boardHeight ||
+       oldv != gameInfo.variant ||
        oldh != gameInfo.holdingsWidth
-#ifdef GOTHIC
-       || oldv == VariantGothic ||        // For licensing popups
-       gameInfo.variant == VariantGothic
-#endif
-#ifdef FALCON
-       || oldv == VariantFalcon ||
-       gameInfo.variant == VariantFalcon
-#endif
                                          )
             InitDrawingSizes(-2 ,0);
 
+    oldv = gameInfo.variant;
     if (redraw)
       DrawPosition(TRUE, boards[currentMove]);
 }
@@ -5991,6 +5985,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
       case BeginningOfGame:
       case AnalyzeMode:
       case Training:
+       if(fromY == DROP_RANK) break; // [HGM] drop moves (entered through move type-in) are automatically assigned to side-to-move
        if ((int) boards[currentMove][fromY][fromX] >= (int) BlackPawn &&
             (int) boards[currentMove][fromY][fromX] < (int) EmptySquare) {
            /* User is moving for Black */
@@ -6085,7 +6080,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", 
@@ -6248,6 +6243,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:
@@ -7334,11 +7330,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;
@@ -7375,7 +7366,11 @@ 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)) {
+           DrawPosition(FALSE, boards[currentMove = forwardMostMove-1]);
+           ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+           return; // [HGM] adjudicate: for all automatic game ends
+       }
 
 #if ZIPPY
        if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) &&
@@ -7697,6 +7692,13 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
            gameMode = EditGame;
            ModeHighlight();
        }
+        /* [HGM] illegal-move claim should forfeit game when Xboard */
+        /* only passes fully legal moves                            */
+        if( appData.testLegality && gameMode == TwoMachinesPlay ) {
+            GameEnds( cps->twoMachinesColor[0] == 'w' ? BlackWins : WhiteWins,
+                                "False illegal-move claim", GE_XBOARD );
+            return; // do not take back move we tested as valid
+        }
        currentMove = forwardMostMove-1;
        DisplayMove(currentMove-1); /* before DisplayMoveError */
        SwitchClocks(forwardMostMove-1); // [HGM] race
@@ -7705,13 +7707,6 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                parseList[currentMove], cps->which);
        DisplayMoveError(buf1);
        DrawPosition(FALSE, boards[currentMove]);
-
-        /* [HGM] illegal-move claim should forfeit game when Xboard */
-        /* only passes fully legal moves                            */
-        if( appData.testLegality && gameMode == TwoMachinesPlay ) {
-            GameEnds( cps->twoMachinesColor[0] == 'w' ? BlackWins : WhiteWins,
-                                "False illegal-move claim", GE_XBOARD );
-        }
        return;
     }
     if (strncmp(message, "time", 4) == 0 && StrStr(message, "Illegal")) {
@@ -8424,7 +8419,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
@@ -9459,6 +9455,13 @@ GameEnds(result, resultDetails, whosays)
                     first.matchWins, second.matchWins,
                     appData.matchGames - (first.matchWins + second.matchWins));
            popupRequested++; // [HGM] crash: postpone to after resetting endingGame
+           if (appData.firstPlaysBlack) { // [HGM] match: back to original for next match
+               first.twoMachinesColor = "black\n";
+               second.twoMachinesColor = "white\n";
+           } else {
+               first.twoMachinesColor = "white\n";
+               second.twoMachinesColor = "black\n";
+           }
        }
     }
     if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) &&
@@ -9922,8 +9925,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);
@@ -12615,6 +12616,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 */
@@ -14540,15 +14565,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();