From fadfab165a805fd2a970999e11b1032480b069dc Mon Sep 17 00:00:00 2001 From: Arthur Bols Date: Thu, 22 Dec 2022 18:31:13 +0100 Subject: [PATCH] [MoveGenerator] Add MoveGenerator --- CMakeLists.txt | 1 + MoveGenerator.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++ MoveGenerator.hpp | 36 +++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 MoveGenerator.cpp create mode 100644 MoveGenerator.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2eb28ef..491d0c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ add_library(cplchess_lib OBJECT EngineFactory.cpp Uci.cpp BitBoard.cpp + MoveGenerator.cpp ) target_include_directories(cplchess_lib PUBLIC .) diff --git a/MoveGenerator.cpp b/MoveGenerator.cpp new file mode 100644 index 0000000..40c0dcc --- /dev/null +++ b/MoveGenerator.cpp @@ -0,0 +1,62 @@ +#include +#include "MoveGenerator.hpp" +#include "Board.hpp" + +MoveGenerator::MoveGenerator(const std::shared_ptr &pieceBB, + const std::shared_ptr &occupiedBB) + : mPieceBBs(pieceBB), mOccupiedBB(occupiedBB) { + +} + +void MoveGenerator::generatePawnMoves(const Square &from, const std::optional &eps, + PieceColor color, MoveVec &moves) const { + + BitBoard targets = 0; + if (eps.has_value()) { + targets |= BitBoard::fromIndex(eps.value().index()); + } + + generatePawnMoves(from, targets, color, moves); +} +void MoveGenerator::generatePawnMoves(const Square &from, PieceColor color, MoveVec &moves) { + generatePawnMoves(from, BitBoard(0), color, moves); +} + +void MoveGenerator::generatePawnMoves(const Square &from, BitBoard targets, PieceColor color, MoveVec &moves) const { + + auto fromBB = BitBoard::fromIndex(from.index()); + targets |= mPieceBBs[Board::toIndex(!color)]; + + BitBoard movesBB; + if (color == PieceColor::White) { + movesBB = BitBoard::pawnNorthAttacks(fromBB, targets) & ~mPieceBBs[Board::toIndex(color)]; + movesBB |= BitBoard::pawnNorthMoves(fromBB, ~*mOccupiedBB); + } else { + movesBB = BitBoard::pawnSouthAttacks(fromBB, targets) & ~mPieceBBs[Board::toIndex(color)]; + movesBB |= BitBoard::pawnSouthMoves(fromBB, ~*mOccupiedBB); + } + + bool isPromotion = movesBB & (Rank1 | Rank8); + if (isPromotion) { + generateMovesWithPromotion(from, movesBB, moves); + } else { + generateMoves(from, movesBB, moves); + } +} + +void MoveGenerator::generateMoves(const Square &from, BitBoard movesBB, MoveGenerator::MoveVec &moves) { + while (movesBB) { + auto to = Square(movesBB.pop()); + moves.emplace_back(from, to, std::nullopt); + } +} + +void MoveGenerator::generateMovesWithPromotion(const Square &from, BitBoard movesBB, MoveGenerator::MoveVec &moves) { + while (movesBB) { + auto to = Square(movesBB.pop()); + for (const auto &kItem : Piece::PromotionTypes) { + moves.emplace_back(from, to, static_cast(kItem)); + } + } +} + diff --git a/MoveGenerator.hpp b/MoveGenerator.hpp new file mode 100644 index 0000000..c9ae940 --- /dev/null +++ b/MoveGenerator.hpp @@ -0,0 +1,36 @@ +#ifndef CHESS_ENGINE_MOVEGENERATOR_HPP +#define CHESS_ENGINE_MOVEGENERATOR_HPP + +#include "Piece.hpp" +#include "Square.hpp" +#include "Move.hpp" +#include "CastlingRights.hpp" +#include "BitBoard.hpp" + +#include +#include +#include +#include + +class MoveGenerator { +public: + using MoveVec = std::vector; + + MoveGenerator(const std::shared_ptr& pieceBB, const std::shared_ptr& occupiedBB); + MoveGenerator(MoveGenerator &) = delete; + MoveGenerator &operator=(MoveGenerator const &) = delete; + + void generatePawnMoves(const Square &from, const std::optional &eps, PieceColor color, MoveVec &moves) const; + void generatePawnMoves(const Square &from, PieceColor color, MoveVec &moves); + +private: + const std::shared_ptr mPieceBBs; + const std::shared_ptr mOccupiedBB; + + void generatePawnMoves(const Square &from, BitBoard targets, PieceColor color, MoveVec &moves) const; + + static void generateMoves(const Square &from, BitBoard movesBB, MoveVec &moves); + static void generateMovesWithPromotion(const Square &from, BitBoard movesBB, MoveVec &moves); +}; + +#endif //CHESS_ENGINE_MOVEGENERATOR_HPP