Treat Betza-defined e.p. capture
authorH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 23 Nov 2016 16:46:20 +0000 (17:46 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Fri, 13 Jan 2017 15:39:23 +0000 (16:39 +0100)
Pieces with redefined moves that include an e.p. capture will now
not be subject to the heuristic that deletes a suspected e.p. victim
during board update (which was only applied to Pawns and Lances).
When they move to the e.p. square (still set by Pawn or Lance multi-
pushes in the old hard-coded way), this will remove the last-moved piece
(which created those e.p. rights).

backend.c

index b5eb581..f465f95 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -10213,14 +10213,14 @@ ParseGameHistory (char *game)
 void
 ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
 {
-  ChessSquare captured = board[toY][toX], piece, pawn, king, killed, killed2; int p, rookX, oldEP, epRank, berolina = 0;
+  ChessSquare captured = board[toY][toX], piece, pawn, king, killed, killed2; int p, rookX, oldEP, epRank, epFile, berolina = 0;
   int promoRank = gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess ? 3 : 1;
 
     /* [HGM] compute & store e.p. status and castling rights for new position */
     /* we can always do that 'in place', now pointers to these rights are passed to ApplyMove */
 
       if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;
-      oldEP = (signed char)board[EP_FILE]; epRank = board[EP_RANK];
+      oldEP = (signed char)board[EP_FILE]; epRank = board[EP_RANK]; epFile = board[EP_FILE];
       board[EP_STATUS] = EP_NONE;
       board[EP_FILE] = board[EP_RANK] = 100;
 
@@ -10254,6 +10254,13 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
       }
 
       pawn = board[fromY][fromX];
+      if(pieceDesc[pawn] && strchr(pieceDesc[pawn], 'e')) { // piece with user-defined e.p. capture
+       if(captured == EmptySquare && toX == epFile && (toY == (epRank & 127) || toY + (pawn < BlackPawn ? -1 : 1) == epRank - 128)) {
+           captured = board[epRank + (pawn < BlackPawn ? -1 : 1)][oldEP & berolina-1]; // remove victim
+           board[epRank + (pawn < BlackPawn ? -1 : 1)][oldEP & berolina-1] = EmptySquare;
+           pawn = EmptySquare; // kludge to suppress old e.p. code
+       }
+      }
       if( pawn == WhiteLance || pawn == BlackLance ) {
            if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantChu ) {
                if(gameInfo.variant == VariantSpartan) board[EP_STATUS] = EP_PAWN_MOVE; // in Spartan no e.p. rights must be set