17#ifndef HOOVER_CHESS_UTILS__PGN_READER__CHESSBOARD_MOVEGEN_BY_DEST_H_INCLUDED
18#define HOOVER_CHESS_UTILS__PGN_READER__CHESSBOARD_MOVEGEN_BY_DEST_H_INCLUDED
26template <MoveGenType type,
typename MoveStoreFn>
29 SquareSet srcSqMask,
Square dst,
typename MoveStoreFn::Store &store)
noexcept
34 static_assert(
static_cast<std::uint8_t
>(
Color::WHITE) == 0U);
35 static_assert(
static_cast<std::uint8_t
>(
Color::BLACK) == 8U);
37 const Color turn { board.getTurn() };
39 SquareSet { dst } & ~board.getOccupancyMask() &
40 blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) };
44 const SquareSet singleAdvancingPawnSquare {
47 const SquareSet doubleAdvancingPawnSquare {
48 (
PawnLookups::rank3(turn) & singleAdvancingPawnSquare &~ board.getOccupancyMask()).rotr(pawnAdvanceShift) };
51 (singleAdvancingPawnSquare | doubleAdvancingPawnSquare) &
52 board.getPawns() & board.getPiecesInTurn() & srcSqMask };
54 if (advancingPawn !=
SquareSet { }) [[likely]]
64template <MoveGenType type>
68 generateMovesForPawnAndDestNoCaptureStoreFnTempl<type, SingleMoveStoreMoveNoDupCheckFn>(board, srcSqMask, dst, ret);
72template <MoveGenType type>
75 auto i = moves.begin();
76 generateMovesForPawnAndDestNoCaptureStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
77 board, srcSqMask, dst, i);
78 return i - moves.begin();
81template <MoveGenType type,
typename MoveStoreFn>
84 SquareSet srcSqMask,
Square dst,
typename MoveStoreFn::Store &store)
noexcept
89 static_assert(
static_cast<std::uint8_t
>(
Color::WHITE) == 0U);
90 static_assert(
static_cast<std::uint8_t
>(
Color::BLACK) == 8U);
92 const Color turn { board.getTurn() };
94 if (dst != board.getEpSquare()) [[likely]]
97 constexpr SquareSet dstSqMask { 0x00'FF'FF'FF'FF'FF'FF'00 };
100 (blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) &
101 board.getOccupancyMask() & dstSqBit & dstSqMask & ~board.getPiecesInTurn()).allIfAny() };
108 if (Attacks::pinCheck(src, SquareSet { dst }, board.getKingInTurn(), board.getPinnedPieces()))
120 if (Attacks::pinCheck(src, SquareSet { dst }, board.getKingInTurn(), board.getPinnedPieces()))
128template <MoveGenType type>
131 Move ret { Move::illegalNoMove() };
132 generateMovesForPawnAndDestCaptureStoreFnTempl<type, SingleMoveStoreMoveFn>(board, srcSqMask, dst, ret);
136template <MoveGenType type>
139 auto i = moves.begin();
140 generateMovesForPawnAndDestCaptureStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
141 board, srcSqMask, dst, i);
142 return i - moves.begin();
145template <MoveGenType type,
typename MoveStoreFn>
150 static_assert(type == MoveGenType::NO_CHECK || type == MoveGenType::CHECK);
153 static_assert(
static_cast<std::uint8_t
>(Color::WHITE) == 0U);
154 static_assert(
static_cast<std::uint8_t
>(Color::BLACK) == 8U);
156 const Color turn { board.getTurn() };
158 SquareSet { dst } & ~board.getOccupancyMask() &
159 blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) };
162 const SquareSet allowedDstSqMask { PawnLookups::rank8(turn) };
163 const auto pawnAdvanceShift = PawnLookups::pawnAdvanceShift(turn);
165 const SquareSet singleAdvancingPawnSquare { (allowedDstSqMask & dstSqBit).rotr(pawnAdvanceShift) };
168 singleAdvancingPawnSquare &
169 board.getPawns() & board.getPiecesInTurn() & srcSqMask };
171 if (advancingPawn !=
SquareSet { }) [[likely]]
174 if (Attacks::pinCheck(src,
SquareSet { dst }, board.getKingInTurn(), board.getPinnedPieces())) [[likely]]
181template <MoveGenType type>
184 Move ret { Move::illegalNoMove() };
185 generateMovesForPawnAndDestPromoNoCaptureStoreFnTempl<type, SingleMoveStoreMoveNoDupCheckFn>(
186 board, srcSqMask, dst, promo, ret);
190template <MoveGenType type>
193 auto i = moves.begin();
194 generateMovesForPawnAndDestPromoNoCaptureStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
195 board, srcSqMask, dst, promo, i);
196 return i - moves.begin();
199template <MoveGenType type,
typename MoveStoreFn>
204 static_assert(type == MoveGenType::NO_CHECK || type == MoveGenType::CHECK);
206 const Color turn { board.getTurn() };
209 const SquareSet dstSqMask { PawnLookups::rank8(turn) };
212 (blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) &
213 board.getOccupancyMask() & dstSqBit & dstSqMask & ~board.getPiecesInTurn()).allIfAny() };
218 srcSqMask & board.getPawns() & board.getPiecesInTurn() & Attacks::getPawnAttackerMask(dst, turn),
220 if (Attacks::pinCheck(src, SquareSet { dst }, board.getKingInTurn(), board.getPinnedPieces()))
227template <MoveGenType type>
230 Move ret { Move::illegalNoMove() };
231 generateMovesForPawnAndDestPromoCaptureStoreFnTempl<type, SingleMoveStoreMoveFn>(
232 board, srcSqMask, dst, promo, ret);
236template <MoveGenType type>
239 auto i = moves.begin();
240 generateMovesForPawnAndDestPromoCaptureStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
241 board, srcSqMask, dst, promo, i);
242 return i - moves.begin();
245template <MoveGenType type,
typename MoveStoreFn>
248 SquareSet srcSqMask,
Square dst,
typename MoveStoreFn::Store &store)
noexcept
250 static_assert(type == MoveGenType::NO_CHECK || type == MoveGenType::CHECK);
254 blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) &
255 ((board.getPiecesInTurn() &
SquareSet { dst }).allIfNone()
256 & board.getPiecesInTurn() & board.getKnights() & srcSqMask & Attacks::getKnightAttackMask(dst) &~ board.getPinnedPieces()),
258 MoveStoreFn::storeMove(store, Move { src, dst, MoveTypeAndPromotion::REGULAR_KNIGHT_MOVE });
262template <MoveGenType type>
265 Move ret { Move::illegalNoMove() };
266 generateMovesForKnightAndDestStoreFnTempl<type, SingleMoveStoreMoveFn>(board, srcSqMask, dst, ret);
270template <MoveGenType type>
273 ShortMoveList::iterator i { moves.begin() };
274 generateMovesForKnightAndDestStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
275 board, srcSqMask, dst, i);
276 return i - moves.begin();
279template <MoveGenType type, MoveTypeAndPromotion moveType,
typename MoveStoreFn>
282 SquareSet srcSqMask,
Square dst,
typename MoveStoreFn::Store &store)
noexcept
284 static_assert(type == MoveGenType::NO_CHECK || type == MoveGenType::CHECK);
287 moveType == MoveTypeAndPromotion::REGULAR_BISHOP_MOVE ||
288 moveType == MoveTypeAndPromotion::REGULAR_ROOK_MOVE ||
289 moveType == MoveTypeAndPromotion::REGULAR_QUEEN_MOVE);
293 if constexpr (moveType == MoveTypeAndPromotion::REGULAR_BISHOP_MOVE)
295 pieces = Attacks::getBishopAttackMask(dst, board.getOccupancyMask())
296 & srcSqMask & board.getPiecesInTurn() & board.getBishopsAndQueens() & (~board.getRooksAndQueens());
298 else if constexpr (moveType == MoveTypeAndPromotion::REGULAR_ROOK_MOVE)
300 pieces = Attacks::getRookAttackMask(dst, board.getOccupancyMask())
301 & srcSqMask & board.getPiecesInTurn() & (~board.getBishopsAndQueens()) & board.getRooksAndQueens();
305 static_assert(moveType == MoveTypeAndPromotion::REGULAR_QUEEN_MOVE);
307 pieces = Attacks::getQueenAttackMask(dst, board.getOccupancyMask())
308 & srcSqMask & board.getPiecesInTurn() & board.getBishopsAndQueens() & board.getRooksAndQueens();
313 blocksAllChecksMaskTempl<type>(board.getKingInTurn(), board.getCheckers(), dst) &
314 ((board.getPiecesInTurn() &
SquareSet { dst }).allIfNone()
317 if (Attacks::pinCheck(src, SquareSet { dst }, board.getKingInTurn(), board.getPinnedPieces()))
319 MoveStoreFn::storeMove(store,
Move { src, dst, moveType });
324template <MoveGenType type>
327 Move ret { Move::illegalNoMove() };
333template <MoveGenType type>
336 ShortMoveList::iterator i { moves.begin() };
339 board, srcSqMask, dst, i);
340 return i - moves.begin();
343template <MoveGenType type>
346 Move ret { Move::illegalNoMove() };
352template <MoveGenType type>
355 ShortMoveList::iterator i { moves.begin() };
358 board, srcSqMask, dst, i);
359 return i - moves.begin();
362template <MoveGenType type>
365 Move ret { Move::illegalNoMove() };
371template <MoveGenType type>
374 ShortMoveList::iterator i { moves.begin() };
377 board, srcSqMask, dst, i);
378 return i - moves.begin();
381template <MoveGenType type,
typename MoveStoreFn>
384 SquareSet srcSqMask,
Square dst,
typename MoveStoreFn::Store &store)
noexcept
387 const SquareSet srcSqBit { board.getKingInTurn() };
390 Attacks::determineAttackers(
391 board.getOccupancyMask() & ~srcSqBit,
392 board.getPiecesInTurn() & ~srcSqBit,
395 board.getBishopsAndQueens(),
396 board.getRooksAndQueens(),
397 board.getKings() & ~srcSqBit,
402 if (((board.getPiecesInTurn() & dstSqBit).allIfNone() &
403 kingAttackers.allIfNone() &
404 srcSqMask &
SquareSet { board.getKingInTurn() } & Attacks::getKingAttackMask(dst)) !=
SquareSet { })
406 MoveStoreFn::storeMove(store,
Move { board.getKingInTurn(), dst, MoveTypeAndPromotion::REGULAR_KING_MOVE });
410template <MoveGenType type>
413 Move ret { Move::illegalNoMove() };
414 generateMovesForKingAndDestStoreFnTempl<type, SingleMoveStoreMoveFn>(
415 board, srcSqMask, dst, ret);
419template <MoveGenType type>
422 ShortMoveList::iterator i { moves.begin() };
423 generateMovesForKingAndDestStoreFnTempl<type, IteratorStoreMoveFn<ShortMoveList::iterator> >(
424 board, srcSqMask, dst, i);
425 return i - moves.begin();
428template <MoveGenType type>
431 static_assert(type == MoveGenType::NO_CHECK);
434 Attacks::determineAttackedSquares(
435 board.getOccupancyMask() &~ (board.getKings() & board.getPiecesInTurn()),
436 board.getPawns() &~ board.getPiecesInTurn(),
437 board.getKnights() &~ board.getPiecesInTurn(),
438 board.getBishopsAndQueens() &~ board.getPiecesInTurn(),
439 board.getRooksAndQueens() &~ board.getPiecesInTurn(),
440 board.getKingNotInTurn(),
443 Move ret { Move::illegalNoMove() };
444 generateMovesForCastlingStoreFnTempl<MoveGenType::NO_CHECK, SingleMoveStoreMoveNoDupCheckFn, false>(
445 board, attackedSquares, ret);
449template <MoveGenType type>
452 static_assert(type == MoveGenType::NO_CHECK);
455 ShortMoveList::iterator i { moves.begin() };
458 Attacks::determineAttackedSquares(
459 board.getOccupancyMask() &~ (board.getKings() & board.getPiecesInTurn()),
460 board.getPawns() &~ board.getPiecesInTurn(),
461 board.getKnights() &~ board.getPiecesInTurn(),
462 board.getBishopsAndQueens() &~ board.getPiecesInTurn(),
463 board.getRooksAndQueens() &~ board.getPiecesInTurn(),
464 board.getKingNotInTurn(),
470 return i - moves.begin();
473template <MoveGenType type>
476 static_assert(type == MoveGenType::NO_CHECK);
479 Attacks::determineAttackedSquares(
480 board.getOccupancyMask() &~ (board.getKings() & board.getPiecesInTurn()),
481 board.getPawns() &~ board.getPiecesInTurn(),
482 board.getKnights() &~ board.getPiecesInTurn(),
483 board.getBishopsAndQueens() &~ board.getPiecesInTurn(),
484 board.getRooksAndQueens() &~ board.getPiecesInTurn(),
485 board.getKingNotInTurn(),
488 Move ret { Move::illegalNoMove() };
489 generateMovesForCastlingStoreFnTempl<MoveGenType::NO_CHECK, SingleMoveStoreMoveNoDupCheckFn, true>(
490 board, attackedSquares, ret);
494template <MoveGenType type>
497 static_assert(type == MoveGenType::NO_CHECK);
500 ShortMoveList::iterator i { moves.begin() };
503 Attacks::determineAttackedSquares(
504 board.getOccupancyMask() &~ (board.getKings() & board.getPiecesInTurn()),
505 board.getPawns() &~ board.getPiecesInTurn(),
506 board.getKnights() &~ board.getPiecesInTurn(),
507 board.getBishopsAndQueens() &~ board.getPiecesInTurn(),
508 board.getRooksAndQueens() &~ board.getPiecesInTurn(),
509 board.getKingNotInTurn(),
515 return i - moves.begin();
static SquareSet getPawnAttackerMask(Square sq, Color pawnColor) noexcept
Returns a set of squares from which a pawn can attack.
Definition bitboard-attacks.h:111
static bool pinCheck(Square src, SquareSet dstBit, Square kingSq, SquareSet pinnedPieces) noexcept
Checks whether a move by a possibly pinned piece does not expose a check.
Definition bitboard-attacks.h:359
The chessboard.
Definition chessboard.h:589
A legal move. Important: see the note!
Definition chessboard.h:198
static constexpr Move illegalNoMove() noexcept
Token for illegal move: no moves generated.
Definition chessboard.h:429
static SquareSet rank3(Color turn) noexcept
Definition pawn-lookups.h:181
static SquareSet singleAdvanceNoPromoLegalDstMask(Color turn) noexcept
Definition pawn-lookups.h:176
static std::int64_t pawnAdvanceShift(Color turn) noexcept
Definition pawn-lookups.h:191
Set of squares. Implemented using a bit-mask.
Definition chessboard-types-squareset.h:35
constexpr Square firstSquare() const noexcept
Returns the first (lowest-value) square in the set or Square::NONE if the set is empty.
Definition chessboard-types-squareset.h:105
Piece
Named piece.
Definition chessboard-types.h:204
std::array< CompactMove, 8U > ShortMoveList
Short move list returned by move generators for writing a SAN move. That is, when the piece type and ...
Definition chessboard.h:514
Color
Color of a piece or side to move.
Definition chessboard-types.h:194
Square
Named square.
Definition chessboard-types.h:122
#define SQUARESET_ENUMERATE(sq, squareSet,...)
Enumerates all squares in a square set.
Definition chessboard-types-squareset.h:623
@ EN_PASSANT
Pawn en-passant capture.
@ REGULAR_PAWN_MOVE
Regular non-capturing or capturing move (no promotion or en passant)
@ BLACK
Black piece or black side to move.
@ WHITE
White piece or white side to move.
@ NO_CHECK
Move generator for when the king is not in check. All moves are considered.
@ CHECK
Move generator for when the king is in check (single). King moves are considered first,...
Definition chessboard-types-squareset.h:30
std::size_t generateMovesForLongCastlingTempl(const ChessBoard &board, ShortMoveList &moves) noexcept
Definition chessboard-movegen-by-dest.h:450
void generateMovesForPawnAndDestNoCaptureStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:27
Move generateSingleMoveForRookAndDestTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:344
std::size_t generateMovesForShortCastlingTempl(const ChessBoard &board, ShortMoveList &moves) noexcept
Definition chessboard-movegen-by-dest.h:495
void generateMovesForCastlingStoreFnTempl(const ChessBoard &board, SquareSet attackedSquares, typename MoveStoreFn::Store &store) noexcept
Generates the legal castling move, if any.
Definition chessboard-movegen.h:175
Move generateSingleMoveForKingAndDestTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:411
void generateMovesForPawnAndDestPromoCaptureStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, Piece promo, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:200
void generateMovesForSliderAndDestStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:280
constexpr MoveTypeAndPromotion pieceToTypeAndPromotion(Piece promotion) noexcept
Definition chessboard-movegen.h:75
std::size_t generateMovesForKingAndDestTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:420
Move generateSingleMoveForPawnAndDestCaptureTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:129
void generateMovesForPawnAndDestPromoNoCaptureStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, Piece promo, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:146
Move generateSingleMoveForPawnAndDestPromoCaptureTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, Piece promo) noexcept
Definition chessboard-movegen-by-dest.h:228
std::size_t generateMovesForPawnAndDestCaptureTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:137
std::size_t generateMovesForPawnAndDestPromoCaptureTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst, Piece promo) noexcept
Definition chessboard-movegen-by-dest.h:237
Move generateSingleMoveForPawnAndDestNoCaptureTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:65
Move generateSingleMoveForQueenAndDestTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:363
std::size_t generateMovesForRookAndDestTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:353
void generateMovesForPawnAndDestCaptureStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:82
Move generateSingleMoveForPawnAndDestPromoNoCaptureTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, Piece promo) noexcept
Definition chessboard-movegen-by-dest.h:182
Move generateSingleMoveForLongCastlingTempl(const ChessBoard &board) noexcept
Definition chessboard-movegen-by-dest.h:429
void generateMovesForKnightAndDestStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:246
void generateMovesForKingAndDestStoreFnTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst, typename MoveStoreFn::Store &store) noexcept
Definition chessboard-movegen-by-dest.h:382
std::size_t generateMovesForBishopAndDestTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:334
std::size_t generateMovesForQueenAndDestTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:372
Move generateSingleMoveForKnightAndDestTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:263
std::size_t generateMovesForKnightAndDestTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:271
std::size_t generateMovesForPawnAndDestPromoNoCaptureTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst, Piece promo) noexcept
Definition chessboard-movegen-by-dest.h:191
Move generateSingleMoveForBishopAndDestTempl(const ChessBoard &board, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:325
Move generateSingleMoveForShortCastlingTempl(const ChessBoard &board) noexcept
Definition chessboard-movegen-by-dest.h:474
std::size_t generateMovesForPawnAndDestNoCaptureTempl(const ChessBoard &board, ShortMoveList &moves, SquareSet srcSqMask, Square dst) noexcept
Definition chessboard-movegen-by-dest.h:73
Definition chessboard-priv.h:95
Definition chessboard-priv.h:106