mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +00:00
Teach SEE about pinned pieces
Remove pinned pieces from attacks when calculating SEE value. Algorithm is not perfect, there should be no false positives, but can happen that we miss to remove a pinned piece. Currently we don't cach 100% of cases, but is a tradeoff between speed and accuracy. In any case we stay on the safe side, so we remove an attacker when we are sure it is pinned. About only 0,5% of cases are affected by this patch, not a lot given the hard work: this is a difficult patch! Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
243fa483d7
commit
962216440c
1 changed files with 24 additions and 2 deletions
|
@ -1491,7 +1491,7 @@ void Position::undo_null_move() {
|
||||||
|
|
||||||
|
|
||||||
/// Position::see() is a static exchange evaluator: It tries to estimate the
|
/// Position::see() is a static exchange evaluator: It tries to estimate the
|
||||||
/// material gain or loss resulting from a move. There are three versions of
|
/// material gain or loss resulting from a move. There are three versions of
|
||||||
/// this function: One which takes a destination square as input, one takes a
|
/// this function: One which takes a destination square as input, one takes a
|
||||||
/// move, and one which takes a 'from' and a 'to' square. The function does
|
/// move, and one which takes a 'from' and a 'to' square. The function does
|
||||||
/// not yet understand promotions captures.
|
/// not yet understand promotions captures.
|
||||||
|
@ -1528,6 +1528,11 @@ int Position::see(Square from, Square to) const {
|
||||||
Color us = (from != SQ_NONE ? color_of_piece_on(from) : opposite_color(color_of_piece_on(to)));
|
Color us = (from != SQ_NONE ? color_of_piece_on(from) : opposite_color(color_of_piece_on(to)));
|
||||||
Color them = opposite_color(us);
|
Color them = opposite_color(us);
|
||||||
|
|
||||||
|
// Initialize pinned and pinners bitboards
|
||||||
|
Bitboard pinned[2], pinners[2];
|
||||||
|
pinned[us] = pinned_pieces(us, pinners[us]);
|
||||||
|
pinned[them] = pinned_pieces(them, pinners[them]);
|
||||||
|
|
||||||
// Initialize pieces
|
// Initialize pieces
|
||||||
Piece piece = piece_on(from);
|
Piece piece = piece_on(from);
|
||||||
Piece capture = piece_on(to);
|
Piece capture = piece_on(to);
|
||||||
|
@ -1560,6 +1565,17 @@ int Position::see(Square from, Square to) const {
|
||||||
| (pawn_attacks(WHITE, to) & pawns(BLACK))
|
| (pawn_attacks(WHITE, to) & pawns(BLACK))
|
||||||
| (pawn_attacks(BLACK, to) & pawns(WHITE));
|
| (pawn_attacks(BLACK, to) & pawns(WHITE));
|
||||||
|
|
||||||
|
// Remove our pinned pieces from attacks if the captured piece is not
|
||||||
|
// a pinner, otherwise we could remove a valid "capture the pinner" attack.
|
||||||
|
if (pinned[us] != EmptyBoardBB && !bit_is_set(pinners[us], to))
|
||||||
|
attackers &= ~pinned[us];
|
||||||
|
|
||||||
|
// Remove opponent pinned pieces from attacks if the moving piece is not
|
||||||
|
// a pinner, otherwise we could remove a piece that is no more pinned
|
||||||
|
// due to our pinner piece is moving away.
|
||||||
|
if (pinned[them] != EmptyBoardBB && !bit_is_set(pinners[them], from))
|
||||||
|
attackers &= ~pinned[them];
|
||||||
|
|
||||||
if (from != SQ_NONE)
|
if (from != SQ_NONE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1597,7 +1613,7 @@ int Position::see(Square from, Square to) const {
|
||||||
swapList[0] = seeValues[capture];
|
swapList[0] = seeValues[capture];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Locate the least valuable attacker for the side to move. The loop
|
// Locate the least valuable attacker for the side to move. The loop
|
||||||
// below looks like it is potentially infinite, but it isn't. We know
|
// below looks like it is potentially infinite, but it isn't. We know
|
||||||
// that the side to move still has at least one attacker left.
|
// that the side to move still has at least one attacker left.
|
||||||
for (pt = PAWN; !(attackers & pieces_of_color_and_type(c, pt)); pt++)
|
for (pt = PAWN; !(attackers & pieces_of_color_and_type(c, pt)); pt++)
|
||||||
|
@ -1622,6 +1638,12 @@ int Position::see(Square from, Square to) const {
|
||||||
lastCapturingPieceValue = seeValues[pt];
|
lastCapturingPieceValue = seeValues[pt];
|
||||||
c = opposite_color(c);
|
c = opposite_color(c);
|
||||||
|
|
||||||
|
// Remove pinned pieces from attackers
|
||||||
|
if ( pinned[c] != EmptyBoardBB
|
||||||
|
&& !bit_is_set(pinners[c], to)
|
||||||
|
&& !(pinners[c] & attackers))
|
||||||
|
attackers &= ~pinned[c];
|
||||||
|
|
||||||
// Stop after a king capture
|
// Stop after a king capture
|
||||||
if (pt == KING && (attackers & pieces_of_color(c)))
|
if (pt == KING && (attackers & pieces_of_color(c)))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue