Skip to content

Commit 9417552

Browse files
rn5f107s2vondele
andcommitted
Only set ep square if ep capture is possible
for positions such as: position fen rr6/2q2p1k/2P1b1pp/bB2P1n1/R2B2PN/p4P1P/P1Q4K/1R6 b - - 2 38 moves f7f5 position fen 8/p2r1pK1/6p1/1kp1P1P1/2p5/2P5/8/4R3 b - - 0 43 moves f7f5 position fen 4k3/4p3/2b3b1/3P1P2/4K3/8/8/8 b - - moves e7e5 ep is not possible for various reasons. Do not set the ep square and the do not change the zobrist key, as if ep were possible. This fixes 3-fold detection, which could in rare cases be observed as a warning generated by fastchess for PVs that continued beyond an actual 3-fold. Also fixes wrong evals for certain moves e.g. a2a1 for position fen 4k3/1b2p2b/8/3P1P2/4K3/8/8/r7 b - - 0 1 moves e7e5 e4e3 a1a2 e3e4 a2a1 e4f3 a1a2 f3e4 fixes #6138 originally written and tested by rn5f107s2, with small buglet as https://tests.stockfishchess.org/tests/view/685af90843ce022d15794400 failed STC LLR: -2.93 (-2.94,2.94) <-1.75,0.25> Total: 130688 W: 33986 L: 34362 D: 62340 Ptnml(0-2): 414, 13292, 38302, 12928, 408 https://tests.stockfishchess.org/tests/view/688bcb35502b34dd5e7111c9 passed LTC LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 99018 W: 25402 L: 25273 D: 48343 Ptnml(0-2): 54, 9097, 31089, 9204, 65 https://tests.stockfishchess.org/tests/view/688c613c502b34dd5e7112d3 #6211 Bench: 2946135 Co-authored-by: Joost VandeVondele <Joost.VandeVondele@gmail.com>
1 parent 377a3a5 commit 9417552

File tree

2 files changed

+63
-16
lines changed

2 files changed

+63
-16
lines changed

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ help:
903903
echo "Supported archs:" && \
904904
echo "" && \
905905
echo "native > select the best architecture for the host processor (default)" && \
906-
echo "x86-64-avx512icl > x86 64-bit with minimum avx512 support of Intel Ice Lane or AMD Zen 4" && \
906+
echo "x86-64-avx512icl > x86 64-bit with minimum avx512 support of Intel Ice Lake or AMD Zen 4" && \
907907
echo "x86-64-vnni512 > x86 64-bit with vnni 512bit support" && \
908908
echo "x86-64-vnni256 > x86 64-bit with vnni 512bit support, limit operands to 256bit wide" && \
909909
echo "x86-64-avx512 > x86 64-bit with avx512 support" && \

src/position.cpp

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,8 @@ DirtyPiece Position::do_move(Move m,
717717
Piece pc = piece_on(from);
718718
Piece captured = m.type_of() == EN_PASSANT ? make_piece(them, PAWN) : piece_on(to);
719719

720+
bool checkEP = false;
721+
720722
DirtyPiece dp;
721723
dp.pc = pc;
722724
dp.from = from;
@@ -804,21 +806,14 @@ DirtyPiece Position::do_move(Move m,
804806

805807
// Move the piece. The tricky Chess960 castling is handled earlier
806808
if (m.type_of() != CASTLING)
807-
{
808-
809809
move_piece(from, to);
810-
}
811810

812811
// If the moving piece is a pawn do some special extra work
813812
if (type_of(pc) == PAWN)
814813
{
815-
// Set en passant square if the moved pawn can be captured
816-
if ((int(to) ^ int(from)) == 16
817-
&& (attacks_bb<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
818-
{
819-
st->epSquare = to - pawn_push(us);
820-
k ^= Zobrist::enpassant[file_of(st->epSquare)];
821-
}
814+
// Check later if the en passant square needs to be set
815+
if ((int(to) ^ int(from)) == 16)
816+
checkEP = true;
822817

823818
else if (m.type_of() == PROMOTION)
824819
{
@@ -863,11 +858,6 @@ DirtyPiece Position::do_move(Move m,
863858
st->minorPieceKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
864859
}
865860

866-
// Update the key with the final value
867-
st->key = k;
868-
if (tt)
869-
prefetch(tt->first_entry(key()));
870-
871861
// Set capture piece
872862
st->capturedPiece = captured;
873863

@@ -879,6 +869,63 @@ DirtyPiece Position::do_move(Move m,
879869
// Update king attacks used for fast check detection
880870
set_check_info();
881871

872+
// Accurate e.p. info is needed for correct zobrist key generation and 3-fold checking
873+
while (checkEP)
874+
{
875+
auto updateEpSquare = [&] {
876+
st->epSquare = to - pawn_push(us);
877+
k ^= Zobrist::enpassant[file_of(st->epSquare)];
878+
};
879+
880+
Bitboard pawns = attacks_bb<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN);
881+
882+
// If there are no pawns attacking the ep square, ep is not possible
883+
if (!pawns)
884+
break;
885+
886+
// If there are checkers other than the to be captured pawn, ep is never legal
887+
if (checkers() & ~square_bb(to))
888+
break;
889+
890+
if (more_than_one(pawns))
891+
{
892+
// If there are two pawns potentially being abled to capture and at least one
893+
// is not pinned, ep is legal as there are no horizontal exposed checks
894+
if (!more_than_one(blockers_for_king(them) & pawns))
895+
{
896+
updateEpSquare();
897+
break;
898+
}
899+
900+
// If there is no pawn on our king's file, and thus both pawns are pinned
901+
// by bishops, ep is not legal as the king square must be in front of the to square.
902+
// And because the ep square and the king are not on a common diagonal, either ep capture
903+
// would expose the king to a check from one of the bishops
904+
if (!(file_bb(square<KING>(them)) & pawns))
905+
break;
906+
907+
// Otherwise remove the pawn on the king file, as an ep capture by it can never be legal and the
908+
// check below relies on there only being one pawn
909+
pawns &= ~file_bb(square<KING>(them));
910+
}
911+
912+
Square ksq = square<KING>(them);
913+
Square capsq = to;
914+
Bitboard occupied = (pieces() ^ lsb(pawns) ^ capsq) | (to - pawn_push(us));
915+
916+
// If our king is not attacked after making the move, ep is legal.
917+
if (!(attacks_bb<ROOK>(ksq, occupied) & pieces(us, QUEEN, ROOK))
918+
&& !(attacks_bb<BISHOP>(ksq, occupied) & pieces(us, QUEEN, BISHOP)))
919+
updateEpSquare();
920+
921+
break;
922+
}
923+
924+
// Update the key with the final value
925+
st->key = k;
926+
if (tt)
927+
prefetch(tt->first_entry(key()));
928+
882929
// Calculate the repetition info. It is the ply distance from the previous
883930
// occurrence of the same position, negative in the 3-fold case, or zero
884931
// if the position was not repeated.

0 commit comments

Comments
 (0)