BenBot 1.7.5
A chess engine
Loading...
Searching...
No Matches
PseudoLegal.hpp
Go to the documentation of this file.
1/*
2 * ======================================================================================
3 *
4 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7 * ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11 *
12 * ======================================================================================
13 */
14
20
21#pragma once
22
29
39
40using board::Bitboard;
41using pieces::Color;
42
45
47template <Color Side>
48[[nodiscard, gnu::const]] constexpr auto pawn_pushes(
49 Bitboard startingPawns, Bitboard emptySquares) noexcept
50 -> Bitboard;
51
53template <Color Side>
54[[nodiscard, gnu::const]] constexpr auto pawn_double_pushes(
55 Bitboard startingPawns, Bitboard occupiedSquares) noexcept
56 -> Bitboard;
57
62template <Color Side>
63[[nodiscard, gnu::const]] constexpr auto pawn_captures(
64 Bitboard startingPawns, Bitboard enemyPieces) noexcept
65 -> Bitboard;
66
68[[nodiscard, gnu::const]] constexpr auto knight(
69 Bitboard startingKnights, Bitboard friendlyPieces) noexcept
70 -> Bitboard;
71
77[[nodiscard, gnu::const]] constexpr auto bishop(
78 Bitboard startingBishops, Bitboard emptySquares, Bitboard friendlyPieces) noexcept
79 -> Bitboard;
80
86[[nodiscard, gnu::const]] constexpr auto rook(
87 Bitboard startingRooks, Bitboard emptySquares, Bitboard friendlyPieces) noexcept
88 -> Bitboard;
89
95[[nodiscard, gnu::const]] constexpr auto queen(
96 Bitboard startingQueens, Bitboard emptySquares, Bitboard friendlyPieces) noexcept
97 -> Bitboard;
98
100[[nodiscard, gnu::const]] constexpr auto king(
101 Bitboard startingKing, Bitboard friendlyPieces) noexcept
102 -> Bitboard;
103
105
106/*
107 ___ ,--,
108 ,---, ,--.'|_ ,--, ,--.'|
109 ,---.'| | | :,' ,--.'| | | :
110 | | : : : ' : | |, : : ' .--.--.
111 | | | ,---. .;__,' / ,--.--. `--'_ | ' | / / '
112 ,--.__| | / \ | | | / \ ,' ,'| ' | | | : /`./
113 / ,' | / / |:__,'| : .--. .-. | ' | | | | : | : ;_
114. ' / |. ' / | ' : |__ \__\/: . . | | : ' : |__ \ \ `.
115' ; |: |' ; /| | | '.'| ," .--.; | ' : |__ | | '.'| `----. \
116| | '/ '' | / | ; : ;/ / ,. | | | '.'|; : ;/ /`--' /__ ___ ___
117| : :|| : | | , /; : .' \; : ;| , /'--'. / .\/ .\/ .\
118 \ \ / \ \ / ---`-' | , .-./| , / ---`-' `--'---'\ ; \ ; \ ; |
119 `----' `----' `--`---' ---`-' `--" `--" `--"
120
121 */
122
123template <Color Side>
124constexpr auto pawn_pushes(
125 const Bitboard startingPawns, const Bitboard emptySquares) noexcept
126 -> Bitboard
127{
128 return patterns::pawn_pushes<Side>(startingPawns) & emptySquares;
129}
130
131template <Color Side>
132constexpr auto pawn_double_pushes(
133 const Bitboard startingPawns, const Bitboard occupiedSquares) noexcept
134 -> Bitboard
135{
136 namespace ranks = board::masks::ranks;
137
138 const auto moves = patterns::pawn_double_pushes<Side>(startingPawns) & occupiedSquares.inverse();
139
140 // Need to filter out any pushes that would jump over a piece on the third/sixth rank
141 static constexpr auto rankMask = Side == Color::White ? ranks::THREE : ranks::SIX;
142
143 const auto fileMask = board::fills::file(occupiedSquares & rankMask);
144
145 return moves & fileMask.inverse();
146}
147
148template <Color Side>
149constexpr auto pawn_captures(
150 const Bitboard startingPawns, const Bitboard enemyPieces) noexcept
151 -> Bitboard
152{
153 return patterns::pawn_attacks<Side>(startingPawns) & enemyPieces;
154}
155
156constexpr auto knight(
157 const Bitboard startingKnights, const Bitboard friendlyPieces) noexcept
158 -> Bitboard
159{
160 return patterns::knight(startingKnights) & friendlyPieces.inverse();
161}
162
163constexpr auto king(
164 const Bitboard startingKing, const Bitboard friendlyPieces) noexcept
165 -> Bitboard
166{
167 return patterns::king(startingKing) & friendlyPieces.inverse();
168}
169
170#ifndef DOXYGEN
171namespace detail {
172
173 // Sliding piece attack generation is implemented using the Kogge-Stone fill algorithms
174 // occluded fills exclude blockers, but include the sliding piece start squares
175 namespace occluded_fills {
176
177 namespace files = board::masks::files;
178
179 inline constexpr auto notAFile = files::A.inverse();
180 inline constexpr auto notHFile = files::H.inverse();
181
182 [[nodiscard, gnu::const]] constexpr auto north(
183 Bitboard rooks, Bitboard empty) noexcept -> Bitboard
184 {
185 rooks |= empty & (rooks << 8uz);
186 empty &= (empty << 8uz);
187 rooks |= empty & (rooks << 16uz);
188 empty &= (empty << 16uz);
189 rooks |= empty & (rooks << 32uz);
190
191 return rooks;
192 }
193
194 [[nodiscard, gnu::const]] constexpr auto south(
195 Bitboard rooks, Bitboard empty) noexcept -> Bitboard
196 {
197 rooks |= empty & (rooks >> 8uz);
198 empty &= (empty >> 8uz);
199 rooks |= empty & (rooks >> 16uz);
200 empty &= (empty >> 16uz);
201 rooks |= empty & (rooks >> 32uz);
202
203 return rooks;
204 }
205
206 [[nodiscard, gnu::const]] constexpr auto east(
207 Bitboard rooks, Bitboard empty) noexcept -> Bitboard
208 {
209 empty &= notAFile;
210
211 rooks |= empty & (rooks << 1uz);
212 empty &= (empty << 1uz);
213 rooks |= empty & (rooks << 2uz);
214 empty &= (empty << 2uz);
215 rooks |= empty & (rooks << 4uz);
216
217 return rooks;
218 }
219
220 [[nodiscard, gnu::const]] constexpr auto west(
221 Bitboard rooks, Bitboard empty) noexcept -> Bitboard
222 {
223 empty &= notHFile;
224
225 rooks |= empty & (rooks >> 1uz);
226 empty &= (empty >> 1uz);
227 rooks |= empty & (rooks >> 2uz);
228 empty &= (empty >> 2uz);
229 rooks |= empty & (rooks >> 4uz);
230
231 return rooks;
232 }
233
234 [[nodiscard, gnu::const]] constexpr auto northeast(
235 Bitboard bishops, Bitboard empty) noexcept -> Bitboard
236 {
237 empty &= notAFile;
238
239 bishops |= empty & (bishops << 9uz);
240 empty &= (empty << 9uz);
241 bishops |= empty & (bishops << 18uz);
242 empty &= (empty << 18uz);
243 bishops |= empty & (bishops << 36uz);
244
245 return bishops;
246 }
247
248 [[nodiscard, gnu::const]] constexpr auto southeast(
249 Bitboard bishops, Bitboard empty) noexcept -> Bitboard
250 {
251 empty &= notAFile;
252
253 bishops |= empty & (bishops >> 7uz);
254 empty &= (empty >> 7uz);
255 bishops |= empty & (bishops >> 14uz);
256 empty &= (empty >> 14uz);
257 bishops |= empty & (bishops >> 28uz);
258
259 return bishops;
260 }
261
262 [[nodiscard, gnu::const]] constexpr auto northwest(
263 Bitboard bishops, Bitboard empty) noexcept -> Bitboard
264 {
265 empty &= notHFile;
266
267 bishops |= empty & (bishops << 7uz);
268 empty &= (empty << 7uz);
269 bishops |= empty & (bishops << 14uz);
270 empty &= (empty << 14uz);
271 bishops |= empty & (bishops << 28uz);
272
273 return bishops;
274 }
275
276 [[nodiscard, gnu::const]] constexpr auto southwest(
277 Bitboard bishops, Bitboard empty) noexcept -> Bitboard
278 {
279 empty &= notHFile;
280
281 bishops |= empty & (bishops >> 9uz);
282 empty &= (empty >> 9uz);
283 bishops |= empty & (bishops >> 18uz);
284 empty &= (empty >> 18uz);
285 bishops |= empty & (bishops >> 36uz);
286
287 return bishops;
288 }
289
290 } // namespace occluded_fills
291
292 namespace shifts = board::shifts;
293
294 [[nodiscard, gnu::const]] constexpr auto rook_attacks(
295 const Bitboard rooks, const Bitboard emptySquares) noexcept
296 -> Bitboard
297 {
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));
302
303 return northAttacks | southAttacks | eastAttacks | westAttacks;
304 }
305
306 [[nodiscard, gnu::const]] constexpr auto bishop_attacks(
307 const Bitboard bishops, const Bitboard emptySquares) noexcept
308 -> Bitboard
309 {
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));
314
315 return NEattacks | SEattacks | NWattacks | SWattacks;
316 }
317
318} // namespace detail
319#endif // DOXYGEN
320
321constexpr auto rook(
322 const Bitboard startingRooks, const Bitboard emptySquares, const Bitboard friendlyPieces) noexcept
323 -> Bitboard
324{
325 return detail::rook_attacks(startingRooks, emptySquares) & friendlyPieces.inverse();
326}
327
328constexpr auto bishop(
329 const Bitboard startingBishops, const Bitboard emptySquares, const Bitboard friendlyPieces) noexcept
330 -> Bitboard
331{
332 return detail::bishop_attacks(startingBishops, emptySquares) & friendlyPieces.inverse();
333}
334
335constexpr auto queen(
336 const Bitboard startingQueens, const Bitboard emptySquares, const Bitboard friendlyPieces) noexcept
337 -> Bitboard
338{
339 const auto attacks = detail::rook_attacks(startingQueens, emptySquares)
340 | detail::bishop_attacks(startingQueens, emptySquares);
341
342 return attacks & friendlyPieces.inverse();
343}
344
345} // namespace chess::moves::pseudo_legal
constexpr auto bishops(const Color color) noexcept -> Bitboard
Definition Masks.hpp:326
constexpr auto rooks(const Color color) noexcept -> Bitboard
Definition Masks.hpp:308
constexpr auto northeast(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:157
constexpr auto west(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:143
constexpr auto southeast(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:171
constexpr auto northwest(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:185
constexpr auto file(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:213
constexpr auto southwest(Bitboard starting) noexcept -> Bitboard
Definition Fills.hpp:199
constexpr auto king(Bitboard startingKing, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto knight(Bitboard startingKnights, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto rook(Bitboard startingRooks, Bitboard emptySquares, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto pawn_captures(Bitboard startingPawns, Bitboard enemyPieces) noexcept -> Bitboard
constexpr auto pawn_double_pushes(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:105
constexpr auto pawn_pushes(Bitboard startingPawns, Bitboard emptySquares) 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 pawn_double_pushes(Bitboard startingPawns, Bitboard occupiedSquares) noexcept -> Bitboard
constexpr auto king(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:181
constexpr auto queen(Bitboard startingQueens, Bitboard emptySquares, Bitboard friendlyPieces) noexcept -> Bitboard
constexpr auto pawn_pushes(Bitboard starting) noexcept -> Bitboard
Definition Patterns.hpp:98
constexpr auto inverse() const noexcept -> Bitboard
Definition Bitboard.hpp:357