mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 01:03:09 +00:00
Reintroduce SEE verification against discovered attacks
Reintroduces https://github.com/official-stockfish/Stockfish/pull/4453 along with https://github.com/official-stockfish/Stockfish/pull/4469 Leaving out https://github.com/official-stockfish/Stockfish/pull/4533 https://github.com/official-stockfish/Stockfish/pull/4572 Passed STC: https://tests.stockfishchess.org/tests/view/647d8c37726f6b400e408a0a LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 143168 W: 38346 L: 37892 D: 66930 Ptnml(0-2): 352, 15672, 39164, 15962, 434 Passed LTC: https://tests.stockfishchess.org/tests/view/647ee8c528c4431bcb58e432 LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 71538 W: 19560 L: 19190 D: 32788 Ptnml(0-2): 49, 6905, 21499, 7259, 57 closes https://github.com/official-stockfish/Stockfish/pull/4609 bench: 2595430
This commit is contained in:
parent
a9a6915e08
commit
e1dd005583
3 changed files with 34 additions and 9 deletions
|
@ -1061,7 +1061,7 @@ Key Position::key_after(Move m) const {
|
||||||
/// SEE value of move is greater or equal to the given threshold. We'll use an
|
/// 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.
|
/// 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));
|
assert(is_ok(m));
|
||||||
|
|
||||||
|
@ -1080,7 +1080,7 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
assert(color_of(piece_on(from)) == sideToMove);
|
assert(color_of(piece_on(from)) == sideToMove);
|
||||||
Bitboard occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
|
occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
|
||||||
Color stm = sideToMove;
|
Color stm = sideToMove;
|
||||||
Bitboard attackers = attackers_to(to, occupied);
|
Bitboard attackers = attackers_to(to, occupied);
|
||||||
Bitboard stmAttackers, bb;
|
Bitboard stmAttackers, bb;
|
||||||
|
@ -1111,43 +1111,43 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||||
// the bitboard 'attackers' any X-ray attackers behind it.
|
// the bitboard 'attackers' any X-ray attackers behind it.
|
||||||
if ((bb = stmAttackers & pieces(PAWN)))
|
if ((bb = stmAttackers & pieces(PAWN)))
|
||||||
{
|
{
|
||||||
|
occupied ^= least_significant_square_bb(bb);
|
||||||
if ((swap = PawnValueMg - swap) < res)
|
if ((swap = PawnValueMg - swap) < res)
|
||||||
break;
|
break;
|
||||||
occupied ^= least_significant_square_bb(bb);
|
|
||||||
|
|
||||||
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((bb = stmAttackers & pieces(KNIGHT)))
|
else if ((bb = stmAttackers & pieces(KNIGHT)))
|
||||||
{
|
{
|
||||||
|
occupied ^= least_significant_square_bb(bb);
|
||||||
if ((swap = KnightValueMg - swap) < res)
|
if ((swap = KnightValueMg - swap) < res)
|
||||||
break;
|
break;
|
||||||
occupied ^= least_significant_square_bb(bb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((bb = stmAttackers & pieces(BISHOP)))
|
else if ((bb = stmAttackers & pieces(BISHOP)))
|
||||||
{
|
{
|
||||||
|
occupied ^= least_significant_square_bb(bb);
|
||||||
if ((swap = BishopValueMg - swap) < res)
|
if ((swap = BishopValueMg - swap) < res)
|
||||||
break;
|
break;
|
||||||
occupied ^= least_significant_square_bb(bb);
|
|
||||||
|
|
||||||
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((bb = stmAttackers & pieces(ROOK)))
|
else if ((bb = stmAttackers & pieces(ROOK)))
|
||||||
{
|
{
|
||||||
|
occupied ^= least_significant_square_bb(bb);
|
||||||
if ((swap = RookValueMg - swap) < res)
|
if ((swap = RookValueMg - swap) < res)
|
||||||
break;
|
break;
|
||||||
occupied ^= least_significant_square_bb(bb);
|
|
||||||
|
|
||||||
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
|
attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((bb = stmAttackers & pieces(QUEEN)))
|
else if ((bb = stmAttackers & pieces(QUEEN)))
|
||||||
{
|
{
|
||||||
|
occupied ^= least_significant_square_bb(bb);
|
||||||
if ((swap = QueenValueMg - swap) < res)
|
if ((swap = QueenValueMg - swap) < res)
|
||||||
break;
|
break;
|
||||||
occupied ^= least_significant_square_bb(bb);
|
|
||||||
|
|
||||||
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
|
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
|
||||||
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
|
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
|
||||||
|
@ -1162,6 +1162,11 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||||
return bool(res);
|
return bool(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Position::see_ge(Move m, Value threshold) const {
|
||||||
|
Bitboard occupied;
|
||||||
|
return see_ge(m, occupied, threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::is_draw() tests whether the position is drawn by 50-move rule
|
/// Position::is_draw() tests whether the position is drawn by 50-move rule
|
||||||
/// or by repetition. It does not detect stalemates.
|
/// or by repetition. It does not detect stalemates.
|
||||||
|
|
|
@ -144,6 +144,7 @@ public:
|
||||||
|
|
||||||
// Static Exchange Evaluation
|
// Static Exchange Evaluation
|
||||||
bool see_ge(Move m, Value threshold = VALUE_ZERO) const;
|
bool see_ge(Move m, Value threshold = VALUE_ZERO) const;
|
||||||
|
bool see_ge(Move m, Bitboard& occupied, Value threshold = VALUE_ZERO) const;
|
||||||
|
|
||||||
// Accessing hash keys
|
// Accessing hash keys
|
||||||
Key key() const;
|
Key key() const;
|
||||||
|
|
|
@ -990,9 +990,28 @@ moves_loop: // When in check, search starts here
|
||||||
+ captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 7 < alpha)
|
+ captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 7 < alpha)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Bitboard occupied;
|
||||||
// SEE based pruning (~11 Elo)
|
// SEE based pruning (~11 Elo)
|
||||||
if (!pos.see_ge(move, Value(-205) * depth))
|
if (!pos.see_ge(move, occupied, Value(-205) * depth))
|
||||||
|
{
|
||||||
|
if (depth < 2 - capture)
|
||||||
continue;
|
continue;
|
||||||
|
// Don't prune the move if opponent Queen/Rook is under discovered attack after the exchanges
|
||||||
|
// Don't prune the move if opponent King is under discovered attack after or during the exchanges
|
||||||
|
Bitboard leftEnemies = (pos.pieces(~us, KING, QUEEN, ROOK)) & occupied;
|
||||||
|
Bitboard attacks = 0;
|
||||||
|
occupied |= to_sq(move);
|
||||||
|
while (leftEnemies && !attacks)
|
||||||
|
{
|
||||||
|
Square sq = pop_lsb(leftEnemies);
|
||||||
|
attacks |= pos.attackers_to(sq, occupied) & pos.pieces(us) & occupied;
|
||||||
|
// don't consider pieces which were already threatened/hanging before SEE exchanges
|
||||||
|
if (attacks && (sq != pos.square<KING>(~us) && (pos.attackers_to(sq, pos.pieces()) & pos.pieces(us))))
|
||||||
|
attacks = 0;
|
||||||
|
}
|
||||||
|
if (!attacks)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue