123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #ifndef CHESSY_SEARCH_H
- #define CHESSY_SEARCH_H
- #include "ChessGame.h"
- #include <utility>
- namespace chessy
- {
- template<typename T>
- class Search;
- class MinimaxN;
- }
- template<typename T>
- class chessy::Search
- {
- T handler;
- ChessGame& game;
- Board& board;
- Bitboard whites;
- Bitboard blacks;
- public:
- inline Search(T&& handler, ChessGame& game) :
- handler{ handler }, game{ game }, board{ game.getBoard() },
- whites{ board.getWhites() }, blacks{ board.getBlacks() } {}
- template<Side side, typename... Args>
- inline void iterateAll(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateKnights(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateBishops(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateRooks(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateQueens(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateKing(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateCastling(Args&&... args);
- template<Side side, typename... Args>
- inline void iteratePawns(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateSinglePawnPushes(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateDoublePawnPushes(Args&&... args);
- template<Side side, typename... Args>
- inline void iteratePawnCaptures(Args&&... args);
- template<Side side, typename... Args>
- inline void iteratePromotions(Args&&... args);
- template<Side side, typename... Args>
- inline void iterateEnPassant(Args&&... args);
- private:
- template<Side side>
- inline Bitboard friends(void) const
- {
- return side == WHITE_SIDE ? whites : blacks;
- }
- template<Side side>
- inline Bitboard enemies(void) const
- {
- return side == WHITE_SIDE ? blacks : whites;
- }
- };
- class chessy::MinimaxN
- {
- public:
- bool operator () (int a, int b) {
- return true;
- }
- };
- /*inline void aga() {
- chessy::ChessGame cg;
- chessy::MinimaxN mm;
- chessy::Search<chessy::MinimaxN> search = { mm, cg };
- search.iterateAll(5, 7);
- }*/
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateAll(Args&&... args)
- {
- iteratePawns<side, Args...>(std::forward<Args>(args)...);
- iterateKnights<side, Args...>(std::forward<Args>(args)...);
- iterateBishops<side, Args...>(std::forward<Args>(args)...);
- iterateRooks<side, Args...>(std::forward<Args>(args)...);
- iterateQueens<side, Args...>(std::forward<Args>(args)...);
- iterateKing<side, Args...>(std::forward<Args>(args)...);
- iterateCastling<side, Args...>(std::forward<Args>(args)...);
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateKnights(Args&&... args)
- {
- MoveInfo moveInfo;
- Bitboard& ns = board.getKnights<side>();
- PositionSet knights{ ns };
- moveInfo.movedPiece = PieceType::KNIGHT;
- for (auto knight : knights) {
- for (auto pos : KnightMoveGenerator{ knight, friends<side>() }) {
- moveInfo.move = Move{ knight, pos };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateBishops(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::BISHOP;
- PositionSet bishops { board.getBishops<side>() };
- for (auto bishop : bishops) {
- for (auto pos : PrimitiveBishopMoveGenerator{
- bishop, enemies<side>(), friends<side>() }) {
- moveInfo.move = Move{ bishop, pos };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateRooks(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::ROOK;
- PositionSet rooks { board.getRooks<side>() };
- for (auto rook : rooks) {
- for (auto pos : PrimitiveRookMoveGenerator{
- rook, enemies<side>(), friends<side>() }) {
- moveInfo.move = Move{ rook, pos };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateQueens(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::QUEEN;
- PositionSet queens { board.getQueens<side>() };
- for (auto queen : queens) {
- for (auto pos : PrimitiveQueenMoveGenerator{
- queen, enemies<side>(), friends<side>() }) {
- moveInfo.move = Move{ queen, pos };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateKing(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::KING;
- Bitboard king = board.getKing<side>();
- for (auto pos : KingMoveGenerator{ king, friends<side>() }) {
- moveInfo.move = Move{ king.getLeastSignificantBit(), pos };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateCastling(Args&&... args)
- {
- Bitboard king = board.getKing<side>();
- Bitboard allOccupied = whites | blacks;
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::KING;
- if (game.getCanCastleKingSide(side)) {
- Bitboard target = king.bits >> 2; // move king to the right
- Bitboard rook = king.bits << 3;
- Bitboard rookTarget = king.bits >> 1;
- if (!(target & allOccupied) &&
- !(rookTarget & allOccupied)) {
- moveInfo.move = Move{ king.getLeastSignificantBit(),
- target.getLeastSignificantBit(), true };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- if (game.getCanCastleQueenSide(side)) {
- Bitboard target = king.bits << 2; // move king to the left
- Bitboard rook = king.bits >> 3;
- Bitboard rookTarget = king.bits << 1;
- if (!(target & allOccupied) &&
- !(rookTarget & allOccupied)) {
- moveInfo.move = Move{ king.getLeastSignificantBit(),
- target.getLeastSignificantBit(), true };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateSinglePawnPushes(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::PAWN;
- PawnPushGenerator<side> mg{ game };
- for (Move push : mg) {
- moveInfo.move = push;
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateDoublePawnPushes(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::PAWN;
- PawnDoublePushGenerator<side> mg{ game };
- for (Move push : mg) {
- moveInfo.move = push;
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iteratePawnCaptures(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::PAWN;
- PawnCaptureGenerator<side, LEFT> mgl{ game };
- for (Move push : mgl) {
- moveInfo.move = push;
- handler(moveInfo, std::forward<Args>(args)...);
- }
- PawnCaptureGenerator<side, RIGHT> mgr{ game };
- for (Move push : mgr) {
- moveInfo.move = push;
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iteratePromotions(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::PAWN;
- PromotionGenerator<side> pg{ game };
- for (Move promotion : pg) {
- moveInfo.move = promotion;
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iterateEnPassant(Args&&... args)
- {
- MoveInfo moveInfo;
- moveInfo.movedPiece = PieceType::PAWN;
- Index enPassant = game.getEnPassantIndex();
- if (enPassant.index != -1) {
- Bitboard pawns = board.getPawns<side>();
- int rowIndex = side == WHITE_SIDE ? 4 : 3;
- int targetRowIndex = side == WHITE_SIDE ? 5 : 2;
- int columnIndex = enPassant.index;
- Bitboard pawnColumns = 0;
- if (columnIndex > 0)
- pawnColumns |= Bitboard::getColumn(columnIndex - 1);
- if (columnIndex < 7)
- pawnColumns |= Bitboard::getColumn(columnIndex + 1);
- pawns &= rowIndex & pawnColumns;
- moveInfo.enPassantTarget = Index{ enPassant.index, rowIndex };
- Index target{ enPassant.index, targetRowIndex };
- PositionSet sources = pawns;
- for (auto source : sources) {
- moveInfo.move = Move{ source, target };
- handler(moveInfo, std::forward<Args>(args)...);
- }
- }
- }
- template<typename T>
- template<chessy::Side side, typename... Args>
- inline void chessy::Search<T>::iteratePawns(Args&&... args)
- {
- iterateSinglePawnPushes<side, Args...>(std::forward<Args>(args)...);
- iterateDoublePawnPushes<side, Args...>(std::forward<Args>(args)...);
- iteratePawnCaptures<side, Args...>(std::forward<Args>(args)...);
- iteratePromotions<side, Args...>(std::forward<Args>(args)...);
- iterateEnPassant<side, Args...>(std::forward<Args>(args)...);
- }
- #endif // CHESSY_SEARCH_H
|