mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Fix pin-aware SEE
Correct pinners calculation and fix bug with pinned pieces giving check. With this patch 'pinners' only returns sliders with exactly one defensive piece between the slider and the attacked square (in other words, pinners returns exact pinners). This was a co-operation between Marco Costalba, Stphane Nicolet and me. Special thanks to Ronald de Man for reporting the bug with pinned pieces giving check, discussed here: https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/S_4E_Xs5HaE STC: LLR: 2.95 (-2.94,2.94) [-3.00,1.00] Total: 132118 W: 23578 L: 23645 D: 84895 LTC: LLR: 2.95 (-2.94,2.94) [-3.00,1.00] Total: 36424 W: 4770 L: 4670 D: 26984 bench: 6272231
This commit is contained in:
parent
4b0043ae7c
commit
943ae89be1
1 changed files with 24 additions and 18 deletions
|
@ -425,23 +425,28 @@ Phase Position::game_phase() const {
|
||||||
/// slider if removing that piece from the board would result in a position where
|
/// slider if removing that piece from the board would result in a position where
|
||||||
/// square 's' is attacked. For example, a king-attack blocking piece can be either
|
/// square 's' is attacked. For example, a king-attack blocking piece can be either
|
||||||
/// a pinned or a discovered check piece, according if its color is the opposite
|
/// a pinned or a discovered check piece, according if its color is the opposite
|
||||||
/// or the same of the color of the slider. The pinners bitboard get filled with
|
/// or the same of the color of the slider.
|
||||||
/// real and potential pinners.
|
|
||||||
|
|
||||||
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
|
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
|
||||||
|
|
||||||
Bitboard b, p, result = 0;
|
Bitboard result = 0;
|
||||||
|
pinners = 0;
|
||||||
|
|
||||||
// Pinners are sliders that attack 's' when a pinned piece is removed
|
// Snipers are sliders that attack 's' when a piece is removed
|
||||||
pinners = p = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
|
Bitboard snipers = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
|
||||||
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
|
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
|
||||||
|
|
||||||
while (p)
|
while (snipers)
|
||||||
{
|
{
|
||||||
b = between_bb(s, pop_lsb(&p)) & pieces();
|
Square sniperSq = pop_lsb(&snipers);
|
||||||
|
Bitboard b = between_bb(s, sniperSq) & pieces();
|
||||||
|
|
||||||
if (!more_than_one(b))
|
if (!more_than_one(b))
|
||||||
|
{
|
||||||
result |= b;
|
result |= b;
|
||||||
|
if (b & pieces(color_of(piece_on(s))))
|
||||||
|
pinners |= sniperSq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +977,7 @@ Value Position::see(Move m) const {
|
||||||
Bitboard occupied, attackers, stmAttackers;
|
Bitboard occupied, attackers, stmAttackers;
|
||||||
Value swapList[32];
|
Value swapList[32];
|
||||||
int slIndex = 1;
|
int slIndex = 1;
|
||||||
PieceType captured;
|
PieceType nextVictim;
|
||||||
Color stm;
|
Color stm;
|
||||||
|
|
||||||
assert(is_ok(m));
|
assert(is_ok(m));
|
||||||
|
@ -1004,8 +1009,8 @@ Value Position::see(Move m) const {
|
||||||
stmAttackers = attackers & pieces(stm);
|
stmAttackers = attackers & pieces(stm);
|
||||||
occupied ^= to; // For the case when captured piece is a pinner
|
occupied ^= to; // For the case when captured piece is a pinner
|
||||||
|
|
||||||
// Don't allow pinned pieces to attack as long all pinners (this includes also
|
// Don't allow pinned pieces to attack pieces except the king as long all
|
||||||
// potential ones) are on their original square. When a pinner moves to the
|
// pinners 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.
|
// exchange-square or get captured on it, we fall back to standard SEE behaviour.
|
||||||
if ( (stmAttackers & pinned_pieces(stm))
|
if ( (stmAttackers & pinned_pieces(stm))
|
||||||
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
||||||
|
@ -1020,25 +1025,26 @@ Value Position::see(Move m) const {
|
||||||
// destination square, where the sides alternately capture, and always
|
// destination square, where the sides alternately capture, and always
|
||||||
// capture with the least valuable piece. After each capture, we look for
|
// capture with the least valuable piece. After each capture, we look for
|
||||||
// new X-ray attacks from behind the capturing piece.
|
// new X-ray attacks from behind the capturing piece.
|
||||||
captured = type_of(piece_on(from));
|
nextVictim = type_of(piece_on(from));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
assert(slIndex < 32);
|
assert(slIndex < 32);
|
||||||
|
|
||||||
// Add the new entry to the swap list
|
// Add the new entry to the swap list
|
||||||
swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
|
swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][nextVictim];
|
||||||
|
|
||||||
// Locate and remove the next least valuable attacker
|
// Locate and remove the next least valuable attacker
|
||||||
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
|
nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
|
||||||
stm = ~stm;
|
stm = ~stm;
|
||||||
stmAttackers = attackers & pieces(stm);
|
stmAttackers = attackers & pieces(stm);
|
||||||
if ( (stmAttackers & pinned_pieces(stm))
|
if ( nextVictim != KING
|
||||||
|
&& (stmAttackers & pinned_pieces(stm))
|
||||||
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
|
||||||
stmAttackers &= ~pinned_pieces(stm);
|
stmAttackers &= ~pinned_pieces(stm);
|
||||||
|
|
||||||
++slIndex;
|
++slIndex;
|
||||||
|
|
||||||
} while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture
|
} while (stmAttackers && (nextVictim != KING || (--slIndex, false))); // Stop before a king capture
|
||||||
|
|
||||||
// Having built the swap list, we negamax through it to find the best
|
// Having built the swap list, we negamax through it to find the best
|
||||||
// achievable score from the point of view of the side to move.
|
// achievable score from the point of view of the side to move.
|
||||||
|
|
Loading…
Add table
Reference in a new issue