From 211b194243de81ed013566a30ef754018586c4e1 Mon Sep 17 00:00:00 2001 From: H.G.Muller <hgm@hgm-xboard.(none)> Date: Wed, 24 Sep 2014 17:02:37 +0200 Subject: [PATCH] Improve virginity test for engine-defined pieces 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 | 8 +++++++- common.h | 2 ++ moves.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/backend.c b/backend.c index 758b71a..749bac9 100644 --- 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 diff --git a/common.h b/common.h index 86a9c5c..cb1278f 100644 --- 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 --- 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; } -- 1.7.0.4