From 76a039027d14640852f60bda6d62ca16bdac3b9e Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Mon, 6 Jul 2020 22:43:54 -0400 Subject: [PATCH] Clean-up en passant processing the goal of this PR is to better document how we process the ep square (if any) given position fen command, and to output more meaningful (and consistent) debug fen on the "d" command. The implementation follows https://en.wikipedia.org/wiki/X-FEN#Encoding_en-passant following x-fen, it is "valid" to record ep even if ep would put king en prise. fixes #2784 closes https://github.com/official-stockfish/Stockfish/pull/2797 No functional change --- src/position.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 6ef7aedc..396bff5f 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -178,9 +178,9 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th 4) En passant target square (in algebraic notation). If there's no en passant target square, this is "-". If a pawn has just made a 2-square move, this - is the position "behind" the pawn. This is recorded only if there is a pawn - in position to make an en passant capture, and if there really is a pawn - that might have advanced two squares. + is the position "behind" the pawn. Following X-FEN standard, this is recorded only + if there is a pawn in position to make an en passant capture, and if there really + is a pawn that might have advanced two squares. 5) Halfmove clock. This is the number of halfmoves since the last pawn advance or capture. This is used to determine if a draw can be claimed under the @@ -251,17 +251,25 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th set_castling_right(c, rsq); } - // 4. En passant square. Ignore if no pawn capture is possible + // 4. En passant square. + // Ignore if square is invalid or not on side to move relative rank 6. + bool enpassant = false; + if ( ((ss >> col) && (col >= 'a' && col <= 'h')) - && ((ss >> row) && (row == '3' || row == '6'))) + && ((ss >> row) && (row == (sideToMove == WHITE ? '6' : '3')))) { st->epSquare = make_square(File(col - 'a'), Rank(row - '1')); - if ( !(attackers_to(st->epSquare) & pieces(sideToMove, PAWN)) - || !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))) - st->epSquare = SQ_NONE; + // En passant square will be considered only if + // a) side to move have a pawn threatening epSquare + // b) there is an enemy pawn in front of epSquare + // c) there is no piece on epSquare or behind epSquare + enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN) + && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))) + && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove)))); } - else + + if (!enpassant) st->epSquare = SQ_NONE; // 5-6. Halfmove clock and fullmove number -- 2.39.2