#ifndef CHESS_ENGINE_BOARD_HPP #define CHESS_ENGINE_BOARD_HPP #include "Piece.hpp" #include "Square.hpp" #include "Move.hpp" #include "CastlingRights.hpp" #include "BitBoard.hpp" #include #include #include #define BB_NUM 8 // 6 pieces, 2 colors class Board { public: using Optional = std::optional; using MoveVec = std::vector; Board(); void setPiece(const Square &square, const Piece::Optional &piece); Piece::Optional piece(const Square &square) const; void setTurn(PieceColor turn); PieceColor turn() const; void setCastlingRights(CastlingRights cr); CastlingRights castlingRights() const; void setEnPassantSquare(const Square::Optional &square); Square::Optional enPassantSquare() const; void makeMove(const Move &move); void pseudoLegalMoves(MoveVec &moves) const; void pseudoLegalMovesFrom(const Square &from, MoveVec &moves) const; private: BitBoard mPieceBBs[BB_NUM] = {}; BitBoard mOccupiedBB = 0; PieceColor mTurn = PieceColor::White; CastlingRights mCR = CastlingRights::None; std::optional mEPS; void handleCastlingRights(const Piece &piece, const BitBoard &bb); // Check if the move is castling without checking the rights or validity. static bool isMoveCastling(const BitBoard &from, const BitBoard &to, const Piece &piece); static inline int toIndex(PieceType t) { return static_cast(t); } static inline int toIndex(PieceColor c) { return static_cast(c); } inline PieceColor pieceColor(const BitBoard &mask) const { auto color = PieceColor::White; if (!(mPieceBBs[static_cast(color)] & mask)) { color = !color; } return color; } inline PieceType pieceType(const BitBoard &mask) const { for (int i = 2; i < BB_NUM; i++) { if (mPieceBBs[i] & mask) { return static_cast(i); } } // Should not happen return static_cast(0); } void handlePawnDoubleAdvance(const Move &move, BitBoard bb, const Piece &movedPiece); void handleEnPassant(const Move &move, const Piece &movedPiece); }; std::ostream &operator<<(std::ostream &os, const Board &board); #endif