mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
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 https://github.com/official-stockfish/Stockfish/issues/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 https://github.com/official-stockfish/Stockfish/pull/6211 Bench: 2946135 Co-authored-by: Joost VandeVondele <Joost.VandeVondele@gmail.com>
This commit is contained in:
committed by
Joost VandeVondele
co-authored by
Joost VandeVondele
parent
377a3a5269
commit
94175524b1
+1
-1
@@ -903,7 +903,7 @@ help:
|
||||
echo "Supported archs:" && \
|
||||
echo "" && \
|
||||
echo "native > select the best architecture for the host processor (default)" && \
|
||||
echo "x86-64-avx512icl > x86 64-bit with minimum avx512 support of Intel Ice Lane or AMD Zen 4" && \
|
||||
echo "x86-64-avx512icl > x86 64-bit with minimum avx512 support of Intel Ice Lake or AMD Zen 4" && \
|
||||
echo "x86-64-vnni512 > x86 64-bit with vnni 512bit support" && \
|
||||
echo "x86-64-vnni256 > x86 64-bit with vnni 512bit support, limit operands to 256bit wide" && \
|
||||
echo "x86-64-avx512 > x86 64-bit with avx512 support" && \
|
||||
|
||||
+62
-15
@@ -717,6 +717,8 @@ DirtyPiece Position::do_move(Move m,
|
||||
Piece pc = piece_on(from);
|
||||
Piece captured = m.type_of() == EN_PASSANT ? make_piece(them, PAWN) : piece_on(to);
|
||||
|
||||
bool checkEP = false;
|
||||
|
||||
DirtyPiece dp;
|
||||
dp.pc = pc;
|
||||
dp.from = from;
|
||||
@@ -804,21 +806,14 @@ DirtyPiece Position::do_move(Move m,
|
||||
|
||||
// Move the piece. The tricky Chess960 castling is handled earlier
|
||||
if (m.type_of() != CASTLING)
|
||||
{
|
||||
|
||||
move_piece(from, to);
|
||||
}
|
||||
|
||||
// If the moving piece is a pawn do some special extra work
|
||||
if (type_of(pc) == PAWN)
|
||||
{
|
||||
// Set en passant square if the moved pawn can be captured
|
||||
if ((int(to) ^ int(from)) == 16
|
||||
&& (attacks_bb<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
|
||||
{
|
||||
st->epSquare = to - pawn_push(us);
|
||||
k ^= Zobrist::enpassant[file_of(st->epSquare)];
|
||||
}
|
||||
// Check later if the en passant square needs to be set
|
||||
if ((int(to) ^ int(from)) == 16)
|
||||
checkEP = true;
|
||||
|
||||
else if (m.type_of() == PROMOTION)
|
||||
{
|
||||
@@ -863,11 +858,6 @@ DirtyPiece Position::do_move(Move m,
|
||||
st->minorPieceKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
|
||||
}
|
||||
|
||||
// Update the key with the final value
|
||||
st->key = k;
|
||||
if (tt)
|
||||
prefetch(tt->first_entry(key()));
|
||||
|
||||
// Set capture piece
|
||||
st->capturedPiece = captured;
|
||||
|
||||
@@ -879,6 +869,63 @@ DirtyPiece Position::do_move(Move m,
|
||||
// Update king attacks used for fast check detection
|
||||
set_check_info();
|
||||
|
||||
// Accurate e.p. info is needed for correct zobrist key generation and 3-fold checking
|
||||
while (checkEP)
|
||||
{
|
||||
auto updateEpSquare = [&] {
|
||||
st->epSquare = to - pawn_push(us);
|
||||
k ^= Zobrist::enpassant[file_of(st->epSquare)];
|
||||
};
|
||||
|
||||
Bitboard pawns = attacks_bb<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN);
|
||||
|
||||
// If there are no pawns attacking the ep square, ep is not possible
|
||||
if (!pawns)
|
||||
break;
|
||||
|
||||
// If there are checkers other than the to be captured pawn, ep is never legal
|
||||
if (checkers() & ~square_bb(to))
|
||||
break;
|
||||
|
||||
if (more_than_one(pawns))
|
||||
{
|
||||
// If there are two pawns potentially being abled to capture and at least one
|
||||
// is not pinned, ep is legal as there are no horizontal exposed checks
|
||||
if (!more_than_one(blockers_for_king(them) & pawns))
|
||||
{
|
||||
updateEpSquare();
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is no pawn on our king's file, and thus both pawns are pinned
|
||||
// by bishops, ep is not legal as the king square must be in front of the to square.
|
||||
// And because the ep square and the king are not on a common diagonal, either ep capture
|
||||
// would expose the king to a check from one of the bishops
|
||||
if (!(file_bb(square<KING>(them)) & pawns))
|
||||
break;
|
||||
|
||||
// Otherwise remove the pawn on the king file, as an ep capture by it can never be legal and the
|
||||
// check below relies on there only being one pawn
|
||||
pawns &= ~file_bb(square<KING>(them));
|
||||
}
|
||||
|
||||
Square ksq = square<KING>(them);
|
||||
Square capsq = to;
|
||||
Bitboard occupied = (pieces() ^ lsb(pawns) ^ capsq) | (to - pawn_push(us));
|
||||
|
||||
// If our king is not attacked after making the move, ep is legal.
|
||||
if (!(attacks_bb<ROOK>(ksq, occupied) & pieces(us, QUEEN, ROOK))
|
||||
&& !(attacks_bb<BISHOP>(ksq, occupied) & pieces(us, QUEEN, BISHOP)))
|
||||
updateEpSquare();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the key with the final value
|
||||
st->key = k;
|
||||
if (tt)
|
||||
prefetch(tt->first_entry(key()));
|
||||
|
||||
// Calculate the repetition info. It is the ply distance from the previous
|
||||
// occurrence of the same position, negative in the 3-fold case, or zero
|
||||
// if the position was not repeated.
|
||||
|
||||
Reference in New Issue
Block a user