48[[nodiscard, gnu::const]]
constexpr auto pawn_pushes(
68[[nodiscard, gnu::const]]
constexpr auto knight(
77[[nodiscard, gnu::const]]
constexpr auto bishop(
86[[nodiscard, gnu::const]]
constexpr auto rook(
95[[nodiscard, gnu::const]]
constexpr auto queen(
100[[nodiscard, gnu::const]]
constexpr auto king(
141 static constexpr auto rankMask = Side == Color::White ? ranks::THREE : ranks::SIX;
145 return moves & fileMask.inverse();
175 namespace occluded_fills {
179 inline constexpr auto notAFile = files::A.inverse();
180 inline constexpr auto notHFile = files::H.inverse();
182 [[nodiscard, gnu::const]]
constexpr auto north(
185 rooks |= empty & (rooks << 8uz);
186 empty &= (empty << 8uz);
187 rooks |= empty & (rooks << 16uz);
188 empty &= (empty << 16uz);
189 rooks |= empty & (rooks << 32uz);
194 [[nodiscard, gnu::const]]
constexpr auto south(
197 rooks |= empty & (rooks >> 8uz);
198 empty &= (empty >> 8uz);
199 rooks |= empty & (rooks >> 16uz);
200 empty &= (empty >> 16uz);
201 rooks |= empty & (rooks >> 32uz);
206 [[nodiscard, gnu::const]]
constexpr auto east(
211 rooks |= empty & (rooks << 1uz);
212 empty &= (empty << 1uz);
213 rooks |= empty & (rooks << 2uz);
214 empty &= (empty << 2uz);
215 rooks |= empty & (rooks << 4uz);
220 [[nodiscard, gnu::const]]
constexpr auto west(
221 Bitboard rooks, Bitboard empty)
noexcept -> Bitboard
226 empty &= (empty >> 1uz);
228 empty &= (empty >> 2uz);
234 [[nodiscard, gnu::const]]
constexpr auto northeast(
235 Bitboard bishops, Bitboard empty)
noexcept -> Bitboard
240 empty &= (empty << 9uz);
242 empty &= (empty << 18uz);
248 [[nodiscard, gnu::const]]
constexpr auto southeast(
249 Bitboard bishops, Bitboard empty)
noexcept -> Bitboard
254 empty &= (empty >> 7uz);
256 empty &= (empty >> 14uz);
262 [[nodiscard, gnu::const]]
constexpr auto northwest(
263 Bitboard bishops, Bitboard empty)
noexcept -> Bitboard
268 empty &= (empty << 7uz);
270 empty &= (empty << 14uz);
276 [[nodiscard, gnu::const]]
constexpr auto southwest(
277 Bitboard bishops, Bitboard empty)
noexcept -> Bitboard
282 empty &= (empty >> 9uz);
284 empty &= (empty >> 18uz);
292 namespace shifts = board::shifts;
294 [[nodiscard, gnu::const]]
constexpr auto rook_attacks(
295 const Bitboard rooks,
const Bitboard emptySquares)
noexcept
298 const auto northAttacks = shifts::north(occluded_fills::north(rooks, emptySquares));
299 const auto southAttacks = shifts::south(occluded_fills::south(rooks, emptySquares));
300 const auto eastAttacks = shifts::east(occluded_fills::east(rooks, emptySquares));
301 const auto westAttacks = shifts::west(occluded_fills::west(rooks, emptySquares));
303 return northAttacks | southAttacks | eastAttacks | westAttacks;
306 [[nodiscard, gnu::const]]
constexpr auto bishop_attacks(
307 const Bitboard bishops,
const Bitboard emptySquares)
noexcept
310 const auto NEattacks = shifts::northeast(occluded_fills::northeast(bishops, emptySquares));
311 const auto SEattacks = shifts::southeast(occluded_fills::southeast(bishops, emptySquares));
312 const auto NWattacks = shifts::northwest(occluded_fills::northwest(bishops, emptySquares));
313 const auto SWattacks = shifts::southwest(occluded_fills::southwest(bishops, emptySquares));
315 return NEattacks | SEattacks | NWattacks | SWattacks;
325 return detail::rook_attacks(startingRooks, emptySquares) & friendlyPieces.
inverse();
332 return detail::bishop_attacks(startingBishops, emptySquares) & friendlyPieces.
inverse();
339 const auto attacks = detail::rook_attacks(startingQueens, emptySquares)
340 | detail::bishop_attacks(startingQueens, emptySquares);
342 return attacks & friendlyPieces.
inverse();