1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 08:43:09 +00:00

Pinned aware SEE

Don't allow pinned pieces to attack the exchange-square as long all
pinners (this includes also potential ones) are on their original
square.
As soon a pinner moves to the exchange-square or get captured on it, we
fall back to standard SEE behaviour.

This correctly handles the majority of cases with absolute pins.

bench: 6883133
This commit is contained in:
Guenther Demetz 2016-09-12 08:47:19 +02:00 committed by Marco Costalba
parent 4c95edddbf
commit 90ce24b11e
3 changed files with 36 additions and 16 deletions

View file

@ -360,7 +360,8 @@ namespace {
if (Pt == QUEEN) if (Pt == QUEEN)
{ {
// Penalty if any relative pin or discovered attack against the queen // Penalty if any relative pin or discovered attack against the queen
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s)) Bitboard pinners;
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
score -= WeakQueen; score -= WeakQueen;
} }
} }

View file

@ -291,8 +291,8 @@ void Position::set_castling_right(Color c, Square rfrom) {
void Position::set_check_info(StateInfo* si) const { void Position::set_check_info(StateInfo* si) const {
si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE)); si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), si->pinnersForKing[WHITE]);
si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK)); si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), si->pinnersForKing[BLACK]);
Square ksq = square<KING>(~sideToMove); Square ksq = square<KING>(~sideToMove);
@ -415,24 +415,25 @@ Phase Position::game_phase() const {
} }
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors) that /// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
/// are blocking attacks on the square 's' from 'sliders'. A piece blocks a slider /// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
/// if removing that piece from the board would result in a position where square 's' /// slider if removing that piece from the board would result in a position where
/// is attacked. For example, a king-attack blocking piece can be either a pinned or /// square 's' is attacked. For example, a king-attack blocking piece can be either
/// a discovered check piece, according if its color is the opposite or the same of /// a pinned or a discovered check piece, according if its color is the opposite
/// the color of the slider. /// or the same of the color of the slider. The pinners bitboard get filled with
/// real and potential pinners.
Bitboard Position::slider_blockers(Bitboard sliders, Square s) const { Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
Bitboard b, pinners, result = 0; Bitboard b, p, result = 0;
// Pinners are sliders that attack 's' when a pinned piece is removed // Pinners are sliders that attack 's' when a pinned piece is removed
pinners = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK)) pinners = p = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders; | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
while (pinners) while (p)
{ {
b = between_bb(s, pop_lsb(&pinners)) & pieces(); b = between_bb(s, pop_lsb(&p)) & pieces();
if (!more_than_one(b)) if (!more_than_one(b))
result |= b; result |= b;
@ -999,6 +1000,18 @@ Value Position::see(Move m) const {
if (!stmAttackers) if (!stmAttackers)
return swapList[0]; return swapList[0];
// Don't allow pinned pieces to attack as long all pinners (this includes also
// potential ones) are on their original square. When a pinner moves to the
// exchange-square or get captured on it, we fall back to standard SEE behaviour.
else if ( (stmAttackers & st->blockersForKing[stm])
&& ((st->pinnersForKing[stm] & (occupied ^ (occupied & to))) == st->pinnersForKing[stm]))
{
// Pinned pieces can't attack so remove them from attackers
stmAttackers ^= (stmAttackers & st->blockersForKing[stm]);
if (!stmAttackers)
return swapList[0];
}
// The destination square is defended, which makes things rather more // The destination square is defended, which makes things rather more
// difficult to compute. We proceed by building up a "swap list" containing // difficult to compute. We proceed by building up a "swap list" containing
// the material gain or loss at each stop in a sequence of captures to the // the material gain or loss at each stop in a sequence of captures to the
@ -1017,6 +1030,11 @@ Value Position::see(Move m) const {
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers); captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm; stm = ~stm;
stmAttackers = attackers & pieces(stm); stmAttackers = attackers & pieces(stm);
if ( stmAttackers
&& (stmAttackers & st->blockersForKing[stm])
&& ((st->pinnersForKing[stm] & (occupied ^ (occupied & to))) == st->pinnersForKing[stm]))
stmAttackers ^= (stmAttackers & st->blockersForKing[stm]);
++slIndex; ++slIndex;
} while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture } while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture

View file

@ -64,6 +64,7 @@ struct StateInfo {
Piece capturedPiece; Piece capturedPiece;
StateInfo* previous; StateInfo* previous;
Bitboard blockersForKing[COLOR_NB]; Bitboard blockersForKing[COLOR_NB];
Bitboard pinnersForKing[COLOR_NB];
Bitboard checkSquares[PIECE_TYPE_NB]; Bitboard checkSquares[PIECE_TYPE_NB];
}; };
@ -121,7 +122,7 @@ public:
Bitboard attacks_from(Piece pc, Square s) const; Bitboard attacks_from(Piece pc, Square s) const;
template<PieceType> Bitboard attacks_from(Square s) const; template<PieceType> Bitboard attacks_from(Square s) const;
template<PieceType> Bitboard attacks_from(Square s, Color c) const; template<PieceType> Bitboard attacks_from(Square s, Color c) const;
Bitboard slider_blockers(Bitboard sliders, Square s) const; Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
// Properties of moves // Properties of moves
bool legal(Move m) const; bool legal(Move m) const;