mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33: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:
parent
4c95edddbf
commit
90ce24b11e
3 changed files with 36 additions and 16 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue