1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 01:03:09 +00:00

Consolidate all attacks bitboards

This is a non-functional simplification that simplifies getting attacks bitboards.

* consolidates all attacks to attacks_bb (remove Position::attacks_from(..)).
* attacks_bb<PieceType>(square) gets pseudo attacks
* attacks_bb<PieceType>(square, bitboard) gets attacks considering occupied squares in the bitboard).
* pawn_attacks_bb(Color, Square) gets pawn attacks like other pawn attack bitboards.
* Wraps all access to PawnAttacks arrays and PseudoAttacks arrays and adds asserts as appropriate.

Passed STC
LLR: 2.95 (-2.94,2.94) {-1.50,0.50}
Total: 90208 W: 17533 L: 17482 D: 55193
Ptnml(0-2): 1412, 10232, 21798, 10217, 1445
https://tests.stockfishchess.org/tests/view/5ece996275787cc0c05d9790

closes https://github.com/official-stockfish/Stockfish/pull/2703

No functional change
This commit is contained in:
protonspring 2020-05-28 09:48:31 -06:00 committed by Joost VandeVondele
parent fb8095718b
commit a5e3b4edde
8 changed files with 76 additions and 72 deletions

View file

@ -112,7 +112,7 @@ namespace {
if ( distance(ksq[WHITE], ksq[BLACK]) <= 1 if ( distance(ksq[WHITE], ksq[BLACK]) <= 1
|| ksq[WHITE] == psq || ksq[WHITE] == psq
|| ksq[BLACK] == psq || ksq[BLACK] == psq
|| (stm == WHITE && (PawnAttacks[WHITE][psq] & ksq[BLACK]))) || (stm == WHITE && (pawn_attacks_bb(WHITE, psq) & ksq[BLACK])))
result = INVALID; result = INVALID;
// Immediate win if a pawn can be promoted without getting captured // Immediate win if a pawn can be promoted without getting captured
@ -120,13 +120,13 @@ namespace {
&& rank_of(psq) == RANK_7 && rank_of(psq) == RANK_7
&& ksq[stm] != psq + NORTH && ksq[stm] != psq + NORTH
&& ( distance(ksq[~stm], psq + NORTH) > 1 && ( distance(ksq[~stm], psq + NORTH) > 1
|| (PseudoAttacks[KING][ksq[stm]] & (psq + NORTH)))) || (attacks_bb<KING>(ksq[stm]) & (psq + NORTH))))
result = WIN; result = WIN;
// Immediate draw if it is a stalemate or a king captures undefended pawn // Immediate draw if it is a stalemate or a king captures undefended pawn
else if ( stm == BLACK else if ( stm == BLACK
&& ( !(PseudoAttacks[KING][ksq[stm]] & ~(PseudoAttacks[KING][ksq[~stm]] | PawnAttacks[~stm][psq])) && ( !(attacks_bb<KING>(ksq[stm]) & ~(attacks_bb<KING>(ksq[~stm]) | pawn_attacks_bb(~stm, psq)))
|| (PseudoAttacks[KING][ksq[stm]] & psq & ~PseudoAttacks[KING][ksq[~stm]]))) || (attacks_bb<KING>(ksq[stm]) & psq & ~attacks_bb<KING>(ksq[~stm]))))
result = DRAW; result = DRAW;
// Position will be classified later // Position will be classified later
@ -149,7 +149,7 @@ namespace {
const Result Bad = (stm == WHITE ? DRAW : WIN); const Result Bad = (stm == WHITE ? DRAW : WIN);
Result r = INVALID; Result r = INVALID;
Bitboard b = PseudoAttacks[KING][ksq[stm]]; Bitboard b = attacks_bb<KING>(ksq[stm]);
while (b) while (b)
r |= stm == WHITE ? db[index(BLACK, ksq[BLACK] , pop_lsb(&b), psq)] r |= stm == WHITE ? db[index(BLACK, ksq[BLACK] , pop_lsb(&b), psq)]

View file

@ -176,6 +176,12 @@ constexpr Bitboard pawn_attacks_bb(Bitboard b) {
: shift<SOUTH_WEST>(b) | shift<SOUTH_EAST>(b); : shift<SOUTH_WEST>(b) | shift<SOUTH_EAST>(b);
} }
inline Bitboard pawn_attacks_bb(Color c, Square s) {
assert(is_ok(s));
return PawnAttacks[c][s];
}
/// pawn_double_attacks_bb() returns the squares doubly attacked by pawns of the /// pawn_double_attacks_bb() returns the squares doubly attacked by pawns of the
/// given color from the squares in the given bitboard. /// given color from the squares in the given bitboard.
@ -266,19 +272,38 @@ inline Bitboard safe_destination(Square s, int step)
return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0); return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
} }
/// attacks_bb() returns a bitboard representing all the squares attacked by a /// attacks_bb(Square) returns the pseudo attacks of the give piece type
/// piece of type Pt (bishop or rook) placed on 's'. /// assuming an empty board.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s) {
assert((Pt != PAWN) && (is_ok(s)));
return PseudoAttacks[Pt][s];
}
/// attacks_bb(Square, Bitboard) returns the attacks by the given piece
/// assuming the board is occupied according to the passed Bitboard.
/// Sliding piece attacks do not continue passed an occupied square.
template<PieceType Pt> template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occupied) { inline Bitboard attacks_bb(Square s, Bitboard occupied) {
const Magic& m = Pt == ROOK ? RookMagics[s] : BishopMagics[s]; assert((Pt != PAWN) && (is_ok(s)));
return m.attacks[m.index(occupied)];
switch (Pt)
{
case BISHOP: return BishopMagics[s].attacks[BishopMagics[s].index(occupied)];
case ROOK : return RookMagics[s].attacks[ RookMagics[s].index(occupied)];
case QUEEN : return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
default : return PseudoAttacks[Pt][s];
}
} }
inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) { inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
assert(pt != PAWN); assert((pt != PAWN) && (is_ok(s)));
switch (pt) switch (pt)
{ {

View file

@ -391,8 +391,8 @@ ScaleFactor Endgame<KQKRPs>::operator()(const Position& pos) const {
&& relative_rank(weakSide, pos.square<KING>(strongSide)) >= RANK_4 && relative_rank(weakSide, pos.square<KING>(strongSide)) >= RANK_4
&& relative_rank(weakSide, rsq) == RANK_3 && relative_rank(weakSide, rsq) == RANK_3
&& ( pos.pieces(weakSide, PAWN) && ( pos.pieces(weakSide, PAWN)
& pos.attacks_from<KING>(kingSq) & attacks_bb<KING>(kingSq)
& pos.attacks_from<PAWN>(rsq, strongSide))) & pawn_attacks_bb(strongSide, rsq)))
return SCALE_FACTOR_DRAW; return SCALE_FACTOR_DRAW;
return SCALE_FACTOR_NONE; return SCALE_FACTOR_NONE;
@ -535,7 +535,7 @@ ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const {
// the corner // the corner
if ( rk == RANK_6 if ( rk == RANK_6
&& distance(psq + 2 * push, ksq) <= 1 && distance(psq + 2 * push, ksq) <= 1
&& (PseudoAttacks[BISHOP][bsq] & (psq + push)) && (attacks_bb<BISHOP>(bsq) & (psq + push))
&& distance<File>(bsq, psq) >= 2) && distance<File>(bsq, psq) >= 2)
return ScaleFactor(8); return ScaleFactor(8);
} }
@ -670,14 +670,14 @@ ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
if ( ksq == blockSq1 if ( ksq == blockSq1
&& opposite_colors(ksq, wbsq) && opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq2 && ( bbsq == blockSq2
|| (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakSide, BISHOP)) || (attacks_bb<BISHOP>(blockSq2, pos.pieces()) & pos.pieces(weakSide, BISHOP))
|| distance<Rank>(psq1, psq2) >= 2)) || distance<Rank>(psq1, psq2) >= 2))
return SCALE_FACTOR_DRAW; return SCALE_FACTOR_DRAW;
else if ( ksq == blockSq2 else if ( ksq == blockSq2
&& opposite_colors(ksq, wbsq) && opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq1 && ( bbsq == blockSq1
|| (pos.attacks_from<BISHOP>(blockSq1) & pos.pieces(weakSide, BISHOP)))) || (attacks_bb<BISHOP>(blockSq1, pos.pieces()) & pos.pieces(weakSide, BISHOP))))
return SCALE_FACTOR_DRAW; return SCALE_FACTOR_DRAW;
else else
return SCALE_FACTOR_NONE; return SCALE_FACTOR_NONE;

View file

@ -235,7 +235,7 @@ namespace {
mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them)); mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
// Initialize attackedBy[] for king and pawns // Initialize attackedBy[] for king and pawns
attackedBy[Us][KING] = pos.attacks_from<KING>(ksq); attackedBy[Us][KING] = attacks_bb<KING>(ksq);
attackedBy[Us][PAWN] = pe->pawn_attacks(Us); attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN]; attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]); attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
@ -243,7 +243,7 @@ namespace {
// Init our king safety tables // Init our king safety tables
Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G), Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
Utility::clamp(rank_of(ksq), RANK_2, RANK_7)); Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
kingRing[Us] = PseudoAttacks[KING][s] | s; kingRing[Us] = attacks_bb<KING>(s) | s;
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them)); kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0; kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
@ -273,7 +273,7 @@ namespace {
// Find attacked squares, including x-ray attacks for bishops and rooks // Find attacked squares, including x-ray attacks for bishops and rooks
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN)) b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK)) : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
: pos.attacks_from<Pt>(s); : attacks_bb<Pt>(s, pos.pieces());
if (pos.blockers_for_king(Us) & s) if (pos.blockers_for_king(Us) & s)
b &= LineBB[pos.square<KING>(Us)][s]; b &= LineBB[pos.square<KING>(Us)][s];
@ -323,7 +323,7 @@ namespace {
* (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles)); * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
// Penalty for all enemy pawns x-rayed // Penalty for all enemy pawns x-rayed
score -= BishopXRayPawns * popcount(PseudoAttacks[BISHOP][s] & pos.pieces(Them, PAWN)); score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
// Bonus for bishop on a long diagonal which can "see" both center squares // Bonus for bishop on a long diagonal which can "see" both center squares
if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center)) if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
@ -438,7 +438,7 @@ namespace {
unsafeChecks |= b2 & attackedBy[Them][BISHOP]; unsafeChecks |= b2 & attackedBy[Them][BISHOP];
// Enemy knights checks // Enemy knights checks
knightChecks = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT]; knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
if (knightChecks & safe) if (knightChecks & safe)
kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100 kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100
: KnightSafeCheck; : KnightSafeCheck;
@ -564,12 +564,12 @@ namespace {
Square s = pos.square<QUEEN>(Them); Square s = pos.square<QUEEN>(Them);
safe = mobilityArea[Us] & ~stronglyProtected; safe = mobilityArea[Us] & ~stronglyProtected;
b = attackedBy[Us][KNIGHT] & pos.attacks_from<KNIGHT>(s); b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
score += KnightOnQueen * popcount(b & safe); score += KnightOnQueen * popcount(b & safe);
b = (attackedBy[Us][BISHOP] & pos.attacks_from<BISHOP>(s)) b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
| (attackedBy[Us][ROOK ] & pos.attacks_from<ROOK >(s)); | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]); score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
} }

View file

@ -40,7 +40,7 @@ namespace {
// Knight promotion is the only promotion that can give a direct check // Knight promotion is the only promotion that can give a direct check
// that's not already included in the queen promotion. // that's not already included in the queen promotion.
if (Type == QUIET_CHECKS && (PseudoAttacks[KNIGHT][to] & ksq)) if (Type == QUIET_CHECKS && (attacks_bb<KNIGHT>(to) & ksq))
*moveList++ = make<PROMOTION>(to - D, to, KNIGHT); *moveList++ = make<PROMOTION>(to - D, to, KNIGHT);
else else
(void)ksq; // Silence a warning under MSVC (void)ksq; // Silence a warning under MSVC
@ -84,8 +84,8 @@ namespace {
if (Type == QUIET_CHECKS) if (Type == QUIET_CHECKS)
{ {
b1 &= pos.attacks_from<PAWN>(ksq, Them); b1 &= pawn_attacks_bb(Them, ksq);
b2 &= pos.attacks_from<PAWN>(ksq, Them); b2 &= pawn_attacks_bb(Them, ksq);
// Add pawn pushes which give discovered check. This is possible only // Add pawn pushes which give discovered check. This is possible only
// if the pawn is not on the same file as the enemy king, because we // if the pawn is not on the same file as the enemy king, because we
@ -166,7 +166,7 @@ namespace {
if (Type == EVASIONS && !(target & (pos.ep_square() - Up))) if (Type == EVASIONS && !(target & (pos.ep_square() - Up)))
return moveList; return moveList;
b1 = pawnsNotOn7 & pos.attacks_from<PAWN>(pos.ep_square(), Them); b1 = pawnsNotOn7 & pawn_attacks_bb(Them, pos.ep_square());
assert(b1); assert(b1);
@ -192,14 +192,14 @@ namespace {
if (Checks) if (Checks)
{ {
if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN) if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN)
&& !(PseudoAttacks[Pt][from] & target & pos.check_squares(Pt))) && !(attacks_bb<Pt>(from) & target & pos.check_squares(Pt)))
continue; continue;
if (pos.blockers_for_king(~us) & from) if (pos.blockers_for_king(~us) & from)
continue; continue;
} }
Bitboard b = pos.attacks_from<Pt>(from) & target; Bitboard b = attacks_bb<Pt>(from, pos.pieces()) & target;
if (Checks) if (Checks)
b &= pos.check_squares(Pt); b &= pos.check_squares(Pt);
@ -248,7 +248,7 @@ namespace {
if (Type != QUIET_CHECKS && Type != EVASIONS) if (Type != QUIET_CHECKS && Type != EVASIONS)
{ {
Square ksq = pos.square<KING>(Us); Square ksq = pos.square<KING>(Us);
Bitboard b = pos.attacks_from<KING>(ksq) & target; Bitboard b = attacks_bb<KING>(ksq) & target;
while (b) while (b)
*moveList++ = make_move(ksq, pop_lsb(&b)); *moveList++ = make_move(ksq, pop_lsb(&b));
@ -303,10 +303,10 @@ ExtMove* generate<QUIET_CHECKS>(const Position& pos, ExtMove* moveList) {
Square from = pop_lsb(&dc); Square from = pop_lsb(&dc);
PieceType pt = type_of(pos.piece_on(from)); PieceType pt = type_of(pos.piece_on(from));
Bitboard b = pos.attacks_from(pt, from) & ~pos.pieces(); Bitboard b = attacks_bb(pt, from, pos.pieces()) & ~pos.pieces();
if (pt == KING) if (pt == KING)
b &= ~PseudoAttacks[QUEEN][pos.square<KING>(~us)]; b &= ~attacks_bb<QUEEN>(pos.square<KING>(~us));
while (b) while (b)
*moveList++ = make_move(from, pop_lsb(&b)); *moveList++ = make_move(from, pop_lsb(&b));
@ -336,7 +336,7 @@ ExtMove* generate<EVASIONS>(const Position& pos, ExtMove* moveList) {
sliderAttacks |= LineBB[ksq][pop_lsb(&sliders)] & ~pos.checkers(); sliderAttacks |= LineBB[ksq][pop_lsb(&sliders)] & ~pos.checkers();
// Generate evasions for king, capture and non capture moves // Generate evasions for king, capture and non capture moves
Bitboard b = pos.attacks_from<KING>(ksq) & ~pos.pieces(us) & ~sliderAttacks; Bitboard b = attacks_bb<KING>(ksq) & ~pos.pieces(us) & ~sliderAttacks;
while (b) while (b)
*moveList++ = make_move(ksq, pop_lsb(&b)); *moveList++ = make_move(ksq, pop_lsb(&b));

View file

@ -100,8 +100,8 @@ namespace {
opposed = theirPawns & forward_file_bb(Us, s); opposed = theirPawns & forward_file_bb(Us, s);
blocked = theirPawns & (s + Up); blocked = theirPawns & (s + Up);
stoppers = theirPawns & passed_pawn_span(Us, s); stoppers = theirPawns & passed_pawn_span(Us, s);
lever = theirPawns & PawnAttacks[Us][s]; lever = theirPawns & pawn_attacks_bb(Us, s);
leverPush = theirPawns & PawnAttacks[Us][s + Up]; leverPush = theirPawns & pawn_attacks_bb(Us, s + Up);
doubled = ourPawns & (s - Up); doubled = ourPawns & (s - Up);
neighbours = ourPawns & adjacent_files_bb(s); neighbours = ourPawns & adjacent_files_bb(s);
phalanx = neighbours & rank_bb(s); phalanx = neighbours & rank_bb(s);
@ -253,7 +253,7 @@ Score Entry::do_king_safety(const Position& pos) {
Bitboard pawns = pos.pieces(Us, PAWN); Bitboard pawns = pos.pieces(Us, PAWN);
int minPawnDist = 6; int minPawnDist = 6;
if (pawns & PseudoAttacks[KING][ksq]) if (pawns & attacks_bb<KING>(ksq))
minPawnDist = 1; minPawnDist = 1;
else while (pawns) else while (pawns)
minPawnDist = std::min(minPawnDist, distance(ksq, pop_lsb(&pawns))); minPawnDist = std::min(minPawnDist, distance(ksq, pop_lsb(&pawns)));

View file

@ -139,7 +139,7 @@ void Position::init() {
for (Piece pc : Pieces) for (Piece pc : Pieces)
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
for (Square s2 = Square(s1 + 1); s2 <= SQ_H8; ++s2) for (Square s2 = Square(s1 + 1); s2 <= SQ_H8; ++s2)
if (PseudoAttacks[type_of(pc)][s1] & s2) if ((type_of(pc) != PAWN) && (attacks_bb(type_of(pc), s1, 0) & s2))
{ {
Move move = make_move(s1, s2); Move move = make_move(s1, s2);
Key key = Zobrist::psq[pc][s1] ^ Zobrist::psq[pc][s2] ^ Zobrist::side; Key key = Zobrist::psq[pc][s1] ^ Zobrist::psq[pc][s2] ^ Zobrist::side;
@ -319,10 +319,10 @@ void Position::set_check_info(StateInfo* si) const {
Square ksq = square<KING>(~sideToMove); Square ksq = square<KING>(~sideToMove);
si->checkSquares[PAWN] = attacks_from<PAWN>(ksq, ~sideToMove); si->checkSquares[PAWN] = pawn_attacks_bb(~sideToMove, ksq);
si->checkSquares[KNIGHT] = attacks_from<KNIGHT>(ksq); si->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
si->checkSquares[BISHOP] = attacks_from<BISHOP>(ksq); si->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
si->checkSquares[ROOK] = attacks_from<ROOK>(ksq); si->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
si->checkSquares[QUEEN] = si->checkSquares[BISHOP] | si->checkSquares[ROOK]; si->checkSquares[QUEEN] = si->checkSquares[BISHOP] | si->checkSquares[ROOK];
si->checkSquares[KING] = 0; si->checkSquares[KING] = 0;
} }
@ -455,8 +455,8 @@ Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners
pinners = 0; pinners = 0;
// Snipers are sliders that attack 's' when a piece and other snipers are removed // Snipers are sliders that attack 's' when a piece and other snipers are removed
Bitboard snipers = ( (PseudoAttacks[ ROOK][s] & pieces(QUEEN, ROOK)) Bitboard snipers = ( (attacks_bb< ROOK>(s) & pieces(QUEEN, ROOK))
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders; | (attacks_bb<BISHOP>(s) & pieces(QUEEN, BISHOP))) & sliders;
Bitboard occupancy = pieces() ^ snipers; Bitboard occupancy = pieces() ^ snipers;
while (snipers) while (snipers)
@ -480,12 +480,12 @@ Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners
Bitboard Position::attackers_to(Square s, Bitboard occupied) const { Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
return (attacks_from<PAWN>(s, BLACK) & pieces(WHITE, PAWN)) return (pawn_attacks_bb(BLACK, s) & pieces(WHITE, PAWN))
| (attacks_from<PAWN>(s, WHITE) & pieces(BLACK, PAWN)) | (pawn_attacks_bb(WHITE, s) & pieces(BLACK, PAWN))
| (attacks_from<KNIGHT>(s) & pieces(KNIGHT)) | (attacks_bb<KNIGHT>(s) & pieces(KNIGHT))
| (attacks_bb< ROOK>(s, occupied) & pieces( ROOK, QUEEN)) | (attacks_bb< ROOK>(s, occupied) & pieces( ROOK, QUEEN))
| (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN)) | (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
| (attacks_from<KING>(s) & pieces(KING)); | (attacks_bb<KING>(s) & pieces(KING));
} }
@ -588,7 +588,7 @@ bool Position::pseudo_legal(const Move m) const {
if ((Rank8BB | Rank1BB) & to) if ((Rank8BB | Rank1BB) & to)
return false; return false;
if ( !(attacks_from<PAWN>(from, us) & pieces(~us) & to) // Not a capture if ( !(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture
&& !((from + pawn_push(us) == to) && empty(to)) // Not a single push && !((from + pawn_push(us) == to) && empty(to)) // Not a single push
&& !( (from + 2 * pawn_push(us) == to) // Not a double push && !( (from + 2 * pawn_push(us) == to) // Not a double push
&& (relative_rank(us, from) == RANK_2) && (relative_rank(us, from) == RANK_2)
@ -596,7 +596,7 @@ bool Position::pseudo_legal(const Move m) const {
&& empty(to - pawn_push(us)))) && empty(to - pawn_push(us))))
return false; return false;
} }
else if (!(attacks_from(type_of(pc), from) & to)) else if (!(attacks_bb(type_of(pc), from, pieces()) & to))
return false; return false;
// Evasions generator already takes care to avoid some kind of illegal moves // Evasions generator already takes care to avoid some kind of illegal moves
@ -670,7 +670,7 @@ bool Position::gives_check(Move m) const {
Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1); Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1); Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
return (PseudoAttacks[ROOK][rto] & square<KING>(~sideToMove)) return (attacks_bb<ROOK>(rto) & square<KING>(~sideToMove))
&& (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove)); && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
} }
default: default:
@ -794,7 +794,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
{ {
// Set en-passant square if the moved pawn can be captured // Set en-passant square if the moved pawn can be captured
if ( (int(to) ^ int(from)) == 16 if ( (int(to) ^ int(from)) == 16
&& (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN))) && (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)))
{ {
st->epSquare = to - pawn_push(us); st->epSquare = to - pawn_push(us);
k ^= Zobrist::enpassant[file_of(st->epSquare)]; k ^= Zobrist::enpassant[file_of(st->epSquare)];

View file

@ -112,9 +112,6 @@ public:
// Attacks to/from a given square // Attacks to/from a given square
Bitboard attackers_to(Square s) const; Bitboard attackers_to(Square s) const;
Bitboard attackers_to(Square s, Bitboard occupied) const; Bitboard attackers_to(Square s, Bitboard occupied) const;
Bitboard attacks_from(PieceType pt, Square s) const;
template<PieceType> Bitboard attacks_from(Square s) const;
template<PieceType> Bitboard attacks_from(Square s, Color c) const;
Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const; Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
// Properties of moves // Properties of moves
@ -284,24 +281,6 @@ inline Square Position::castling_rook_square(CastlingRights cr) const {
return castlingRookSquare[cr]; return castlingRookSquare[cr];
} }
template<PieceType Pt>
inline Bitboard Position::attacks_from(Square s) const {
static_assert(Pt != PAWN, "Pawn attacks need color");
return Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, pieces())
: Pt == QUEEN ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
: PseudoAttacks[Pt][s];
}
template<>
inline Bitboard Position::attacks_from<PAWN>(Square s, Color c) const {
return PawnAttacks[c][s];
}
inline Bitboard Position::attacks_from(PieceType pt, Square s) const {
return attacks_bb(pt, s, pieces());
}
inline Bitboard Position::attackers_to(Square s) const { inline Bitboard Position::attackers_to(Square s) const {
return attackers_to(s, pieces()); return attackers_to(s, pieces());
} }