mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 07:27:46 +00:00
Optimize attackers_to()
https://tests.stockfishchess.org/tests/view/6782decb6ddf09c0b4b6e1b0 LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 105920 W: 27571 L: 27181 D: 51168 Ptnml(0-2): 284, 10808, 30403, 11164, 301 - If we only need to know if attackers exist we can skip some calculations. - Also calculating slider/magic attackers first is better because the double lookup is slow due to memory latency. - I also included a couple of very minor cleanups in search that probably don't warrant their own PR but I can open separately if that's better. closes https://github.com/official-stockfish/Stockfish/pull/5762 No functional change
This commit is contained in:
+18
-9
@@ -493,14 +493,23 @@ void Position::update_slider_blockers(Color c) const {
|
||||
// Slider attacks use the occupied bitboard to indicate occupancy.
|
||||
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
|
||||
|
||||
return (pawn_attacks_bb(BLACK, s) & pieces(WHITE, PAWN))
|
||||
| (pawn_attacks_bb(WHITE, s) & pieces(BLACK, PAWN))
|
||||
| (attacks_bb<KNIGHT>(s) & pieces(KNIGHT))
|
||||
| (attacks_bb<ROOK>(s, occupied) & pieces(ROOK, QUEEN))
|
||||
return (attacks_bb<ROOK>(s, occupied) & pieces(ROOK, QUEEN))
|
||||
| (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
|
||||
| (attacks_bb<KING>(s) & pieces(KING));
|
||||
| (pawn_attacks_bb(BLACK, s) & pieces(WHITE, PAWN))
|
||||
| (pawn_attacks_bb(WHITE, s) & pieces(BLACK, PAWN))
|
||||
| (attacks_bb<KNIGHT>(s) & pieces(KNIGHT)) | (attacks_bb<KING>(s) & pieces(KING));
|
||||
}
|
||||
|
||||
bool Position::attackers_to_exist(Square s, Bitboard occupied, Color c) const {
|
||||
|
||||
return ((attacks_bb<ROOK>(s) & pieces(c, ROOK, QUEEN))
|
||||
&& (attacks_bb<ROOK>(s, occupied) & pieces(c, ROOK, QUEEN)))
|
||||
|| ((attacks_bb<BISHOP>(s) & pieces(c, BISHOP, QUEEN))
|
||||
&& (attacks_bb<BISHOP>(s, occupied) & pieces(c, BISHOP, QUEEN)))
|
||||
|| (((pawn_attacks_bb(~c, s) & pieces(PAWN)) | (attacks_bb<KNIGHT>(s) & pieces(KNIGHT))
|
||||
| (attacks_bb<KING>(s) & pieces(KING)))
|
||||
& pieces(c));
|
||||
}
|
||||
|
||||
// Tests whether a pseudo-legal move is legal
|
||||
bool Position::legal(Move m) const {
|
||||
@@ -542,7 +551,7 @@ bool Position::legal(Move m) const {
|
||||
Direction step = to > from ? WEST : EAST;
|
||||
|
||||
for (Square s = to; s != from; s += step)
|
||||
if (attackers_to(s) & pieces(~us))
|
||||
if (attackers_to_exist(s, pieces(), ~us))
|
||||
return false;
|
||||
|
||||
// In case of Chess960, verify if the Rook blocks some checks.
|
||||
@@ -553,7 +562,7 @@ bool Position::legal(Move m) const {
|
||||
// If the moving piece is a king, check whether the destination square is
|
||||
// attacked by the opponent.
|
||||
if (type_of(piece_on(from)) == KING)
|
||||
return !(attackers_to(to, pieces() ^ from) & pieces(~us));
|
||||
return !(attackers_to_exist(to, pieces() ^ from, ~us));
|
||||
|
||||
// A non-king move is legal if and only if it is not pinned or it
|
||||
// is moving along the ray towards or away from the king.
|
||||
@@ -622,7 +631,7 @@ bool Position::pseudo_legal(const Move m) const {
|
||||
}
|
||||
// In case of king moves under check we have to remove the king so as to catch
|
||||
// invalid moves like b1a1 when opposite queen is on c1.
|
||||
else if (attackers_to(to, pieces() ^ from) & pieces(~us))
|
||||
else if (attackers_to_exist(to, pieces() ^ from, ~us))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1317,7 @@ bool Position::pos_is_ok() const {
|
||||
return true;
|
||||
|
||||
if (pieceCount[W_KING] != 1 || pieceCount[B_KING] != 1
|
||||
|| attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove))
|
||||
|| attackers_to_exist(square<KING>(~sideToMove), pieces(), sideToMove))
|
||||
assert(0 && "pos_is_ok: Kings");
|
||||
|
||||
if ((pieces(PAWN) & (Rank1BB | Rank8BB)) || pieceCount[W_PAWN] > 8 || pieceCount[B_PAWN] > 8)
|
||||
|
||||
Reference in New Issue
Block a user