Skip to content

Commit

Permalink
Clean-up en passant processing
Browse files Browse the repository at this point in the history
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 #2797

No functional change
  • Loading branch information
Rocky640 authored and vondele committed Jul 9, 2020
1 parent 7225d25 commit 76a0390
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions src/position.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 76a0390

Please sign in to comment.