Improve virginity test for engine-defined pieces
authorH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 24 Sep 2014 15:02:37 +0000 (17:02 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Sun, 28 Sep 2014 20:14:28 +0000 (22:14 +0200)
Two squares in the board are now reserved for flags that indicate
whether back-rank pieces have been touched. This allows MovesFromString()
to accurately test virginity of these pieces, rather than having to assume
it when the piece matches that in the opening position. For other ranks
the latter test is still used, as these are normally (irreversible) Pawns,
which cannot return there (and in drop games, when they would, would again
be considered virgin enough for the purpose of double-pushing!).

backend.c
common.h
moves.c

index 758b71a..749bac9 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -6028,9 +6028,10 @@ InitPosition (int redraw)
     gameInfo.boardHeight   = 8;
     gameInfo.holdingsSize  = 0;
     nrCastlingRights = -1; /* [HGM] Kludge to indicate default should be used */
-    for(i=0; i<BOARD_FILES-2; i++)
+    for(i=0; i<BOARD_FILES-6; i++)
       initialPosition[CASTLING][i] = initialRights[i] = NoRights; /* but no rights yet */
     initialPosition[EP_STATUS] = EP_NONE;
+    initialPosition[TOUCHED_W] = initialPosition[TOUCHED_B] = 0;
     SetCharTable(pieceToChar, "PNBRQ...........Kpnbrq...........k");
     if(startVariant == gameInfo.variant) // [HGM] nicks: enable nicknames in original variant
          SetCharTable(pieceNickName, appData.pieceNickNames);
@@ -9941,6 +9942,11 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
           }
        }
 
+       if(fromY == 0) board[TOUCHED_W] |= 1<<fromX; else // new way to keep track of virginity
+       if(fromY == BOARD_HEIGHT-1) board[TOUCHED_B] |= 1<<fromX;
+       if(toY == 0) board[TOUCHED_W] |= 1<<toX; else
+       if(toY == BOARD_HEIGHT-1) board[TOUCHED_B] |= 1<<toX;
+
        for(i=0; i<nrCastlingRights; i++) {
            if(board[CASTLING][i] == fromX && castlingRank[i] == fromY ||
               board[CASTLING][i] == toX   && castlingRank[i] == toY
index 86a9c5c..cb1278f 100644 (file)
--- a/common.h
+++ b/common.h
@@ -180,6 +180,8 @@ typedef char *String;
 #define BOARD_RGHT   (gameInfo.boardWidth + gameInfo.holdingsWidth)
 #define CASTLING     (BOARD_RANKS-1)           /* [HGM] hide in upper rank   */
 #define VIRGIN       (BOARD_RANKS-2)           /* [HGM] pieces not moved     */
+#define TOUCHED_W    CASTLING][(BOARD_FILES-6) /* [HGM] in upper rank        */
+#define TOUCHED_B    CASTLING][(BOARD_FILES-5) /* [HGM] in upper rank        */
 #define EP_RANK      CASTLING][(BOARD_FILES-4) /* [HGM] in upper rank        */
 #define EP_FILE      CASTLING][(BOARD_FILES-3) /* [HGM] in upper rank        */
 #define EP_STATUS    CASTLING][(BOARD_FILES-2) /* [HGM] in upper rank        */
diff --git a/moves.c b/moves.c
index 054ee6b..4831046 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -257,7 +257,9 @@ MovesFromString (Board board, int flags, int f, int r, char *desc, MoveCallback
        if(isdigit(*++p)) expo = atoi(p++);           // read exponent
        if(expo > 9) p++;                             // allow double-digit
        desc = p;                                     // this is start of next move
-       if(initial && board[r][f] != initialPosition[r][f]) continue;
+       if(initial && (board[r][f] != initialPosition[r][f] ||
+                      r == 0              && board[TOUCHED_W] & 1<<f ||
+                      r == BOARD_HEIGHT-1 && board[TOUCHED_B] & 1<<f   ) ) continue;
        if(expo > 1 && dx == 0 && dy == 0) {          // castling indicated by O + number
            mode |= 16; dy = 1;
        }