BenBot 1.7.5
A chess engine
Loading...
Searching...
No Matches
Attacks.hpp
Go to the documentation of this file.
1/*
2 * ======================================================================================
3 *
4 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7 * ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11 *
12 * ======================================================================================
13 */
14
19
20#pragma once
21
22#include <cstddef> // IWYU pragma: keep - for size_t
28
29namespace chess::moves {
30
31using board::Bitboard;
32using board::Pieces;
33using pieces::Color;
34using std::size_t;
35
44template <Color Side>
45[[nodiscard, gnu::const]] constexpr auto squares_attacked(
46 const Pieces& pieces, Bitboard targetSquares, Bitboard enemyPieces) noexcept
47 -> bool;
48
58template <Color Side>
59[[nodiscard, gnu::const]] constexpr auto num_squares_attacked(
60 const Pieces& pieces, Bitboard targetSquares, Bitboard enemyPieces, bool includeKing = true) noexcept
61 -> size_t;
62
63/*
64 ___ ,--,
65 ,---, ,--.'|_ ,--, ,--.'|
66 ,---.'| | | :,' ,--.'| | | :
67 | | : : : ' : | |, : : ' .--.--.
68 | | | ,---. .;__,' / ,--.--. `--'_ | ' | / / '
69 ,--.__| | / \ | | | / \ ,' ,'| ' | | | : /`./
70 / ,' | / / |:__,'| : .--. .-. | ' | | | | : | : ;_
71. ' / |. ' / | ' : |__ \__\/: . . | | : ' : |__ \ \ `.
72' ; |: |' ; /| | | '.'| ," .--.; | ' : |__ | | '.'| `----. \
73| | '/ '' | / | ; : ;/ / ,. | | | '.'|; : ;/ /`--' /__ ___ ___
74| : :|| : | | , /; : .' \; : ;| , /'--'. / .\/ .\/ .\
75 \ \ / \ \ / ---`-' | , .-./| , / ---`-' `--'---'\ ; \ ; \ ; |
76 `----' `----' `--`---' ---`-' `--" `--" `--"
77
78 */
79
80template <Color Side>
81constexpr auto squares_attacked(
82 const Pieces& pieces, const Bitboard targetSquares, const Bitboard enemyPieces) noexcept
83 -> bool
84{
85 // For pawns, knights & kings we use the move pattern generator functions, because the only
86 // difference with the pseudo-legal generator functions is excluding squares occupied by
87 // friendly pieces, a consideration that is irrelevant here. For sliding pieces, the pseudo-legal
88 // generator functions are necessary to consider blocking pieces, but we can use them in a
89 // set-wise manner, e.g., to determine if any Queen attacks any of the target squares.
90
91 if (const auto pawnAttacks = patterns::pawn_attacks<Side>(pieces.pawns);
92 (pawnAttacks & targetSquares).any()) {
93 return true;
94 }
95
96 if (const auto knightAttacks = patterns::knight(pieces.knights);
97 (knightAttacks & targetSquares).any()) {
98 return true;
99 }
100
101 const auto friendlyPieces = pieces.occupied;
102 const auto emptySquares = (friendlyPieces | enemyPieces).inverse();
103
104 // TODO: could try replacing the pseudo-legal funcs with the magics funcs here
105
106 if (const auto queenAttacks = pseudo_legal::queen(pieces.queens, emptySquares, friendlyPieces);
107 (queenAttacks & targetSquares).any()) {
108 return true;
109 }
110
111 if (const auto rookAttacks = pseudo_legal::rook(pieces.rooks, emptySquares, friendlyPieces);
112 (rookAttacks & targetSquares).any()) {
113 return true;
114 }
115
116 if (const auto bishopAttacks = pseudo_legal::bishop(pieces.bishops, emptySquares, friendlyPieces);
117 (bishopAttacks & targetSquares).any()) {
118 return true;
119 }
120
121 // test king last
122 // this function is used for things like detecting if a position is check,
123 // so it's unlikely that the king would be the only relevant attacker of a square
124
125 const auto kingAttacks = patterns::king(pieces.king);
126
127 return (kingAttacks & targetSquares).any();
128}
129
130template <Color Side>
131constexpr auto num_squares_attacked(
132 const Pieces& pieces, const Bitboard targetSquares, const Bitboard enemyPieces, const bool includeKing) noexcept
133 -> size_t
134{
135 const auto friendlyPieces = pieces.occupied;
136 const auto emptySquares = (friendlyPieces | enemyPieces).inverse();
137
138 const auto pawnAttacks = patterns::pawn_attacks<Side>(pieces.pawns);
139 const auto knightAttacks = patterns::knight(pieces.knights);
140 const auto queenAttacks = pseudo_legal::queen(pieces.queens, emptySquares, friendlyPieces);
141 const auto rookAttacks = pseudo_legal::rook(pieces.rooks, emptySquares, friendlyPieces);
142 const auto bishopAttacks = pseudo_legal::bishop(pieces.bishops, emptySquares, friendlyPieces);
143
144 auto allAttacks = pawnAttacks | knightAttacks | queenAttacks | rookAttacks | bishopAttacks;
145
146 if (includeKing) {
147 allAttacks |= patterns::king(pieces.king);
148 }
149
150 return (targetSquares & allAttacks).count();
151}
152
153} // namespace chess::moves
constexpr auto squares_attacked(const Pieces &pieces, Bitboard targetSquares, Bitboard enemyPieces) noexcept -> bool
Definition Attacks.hpp:81
constexpr auto rook(Bitboard startingRooks, Bitboard emptySquares, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto pawn_attacks(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:120
constexpr auto bishop(Bitboard startingBishops, Bitboard emptySquares, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto knight(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:128
constexpr auto king(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:181
constexpr auto queen(Bitboard startingQueens, Bitboard emptySquares, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto num_squares_attacked(const Pieces &pieces, Bitboard targetSquares, Bitboard enemyPieces, bool includeKing=true) noexcept -> size_t
Definition Attacks.hpp:131