From 7f0b5d10ee5428e9895a044f21808e85c598518d Mon Sep 17 00:00:00 2001 From: rn5f107s2 Date: Fri, 23 Jan 2026 15:12:26 +0100 Subject: [PATCH] Only record the ep square from a given FEN if ep is legal When given a FEN with an ep square set, only actually set the ep square if there is a legal ep capture that can be played. Fixes #6563 closes https://github.com/official-stockfish/Stockfish/pull/6564 No functional change --- src/position.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 907dfde40..3bbe60d6d 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -264,23 +264,31 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si) { // 4. En passant square. // Ignore if square is invalid or not on side to move relative rank 6. - bool enpassant = false; + bool enpassant = false, legalEP = false; if (((ss >> col) && (col >= 'a' && col <= 'h')) && ((ss >> row) && (row == (sideToMove == WHITE ? '6' : '3')))) { st->epSquare = make_square(File(col - 'a'), Rank(row - '1')); + Bitboard pawns = attacks_bb(st->epSquare, ~sideToMove) & pieces(sideToMove, PAWN); + Bitboard target = (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))); + Bitboard occ = pieces() ^ target ^ st->epSquare; + // 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 = attacks_bb(st->epSquare, ~sideToMove) & pieces(sideToMove, PAWN) - && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))) + enpassant = pawns + && target && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove)))); + + // If no pawn can execute the en passant capture without leaving the king in check, don't record the epSquare + while (pawns) + legalEP |= !(attackers_to(square(sideToMove), occ ^ pop_lsb(pawns)) & pieces(~sideToMove) & ~target); } - if (!enpassant) + if (!enpassant || !legalEP) st->epSquare = SQ_NONE; // 5-6. Halfmove clock and fullmove number