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

@ -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 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
Piece piece = piece_on(from);
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(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)
break;
@ -1622,6 +1638,12 @@ int Position::see(Square from, Square to) const {
lastCapturingPieceValue = seeValues[pt];
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
if (pt == KING && (attackers & pieces_of_color(c)))
{