1
0
Fork 0
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:
Marco Costalba 2009-02-23 15:19:51 +01:00
parent 243fa483d7
commit 962216440c

View file

@ -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)))
{ {