Verified SEE pruning for capturing and checking moves.

Patch analyzes field after SEE exchanges concluded with a recapture by
the opponent:
if opponent Queen/Rook/King results under attack after the exchanges, we
consider the move sharp and don't prune it.

Important note:
By accident I forgot to adjust 'occupied' when the king takes part in
the exchanges.
As result of this a move is considered sharp too, when opponent king
apparently can evade check by recapturing.
Surprisingly this seems contribute to patch's strength.

STC:
https://tests.stockfishchess.org/tests/view/640b16132644b62c33947397
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 116400 W: 31239 L: 30817 D: 54344
Ptnml(0-2): 350, 12742, 31618, 13116, 374

LTC:
https://tests.stockfishchess.org/tests/view/640c88092644b62c3394c1c5
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 177600 W: 47988 L: 47421 D: 82191
Ptnml(0-2): 62, 16905, 54317, 17436, 80

closes https://github.com/official-stockfish/Stockfish/pull/4453

bench: 5012145
This commit is contained in:
pb00067
2023-03-20 08:56:44 +01:00
committed by Joost VandeVondele
parent 02e4697055
commit 24b37e4586
5 changed files with 37 additions and 17 deletions

View File

@@ -1062,7 +1062,7 @@ Key Position::key_after(Move m) const {
/// SEE value of move is greater or equal to the given threshold. We'll use an
/// algorithm similar to alpha-beta pruning with a null window.
bool Position::see_ge(Move m, Value threshold) const {
bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
assert(is_ok(m));
@@ -1081,7 +1081,7 @@ bool Position::see_ge(Move m, Value threshold) const {
return true;
assert(color_of(piece_on(from)) == sideToMove);
Bitboard occupied = pieces() ^ from ^ to;
occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
@@ -1112,45 +1112,44 @@ bool Position::see_ge(Move m, Value threshold) const {
// the bitboard 'attackers' any X-ray attackers behind it.
if ((bb = stmAttackers & pieces(PAWN)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = PawnValueMg - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(KNIGHT)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = KnightValueMg - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
}
else if ((bb = stmAttackers & pieces(BISHOP)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = BishopValueMg - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}
else if ((bb = stmAttackers & pieces(ROOK)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = RookValueMg - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
}
else if ((bb = stmAttackers & pieces(QUEEN)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = QueenValueMg - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
}