Skip to content

Board

Description

The Board class represents the state of a chess game. It provides functionalities to manipulate the board, execute moves, and query the game state. This class is essential for handling game logic, including move generation, and checking game-ending conditions like checkmate or stalemate.

Moves can be made using the makeMove function, which takes a Move object as an argument and also taken back using the unmakeMove function. The makeNullMove and unmakeNullMove functions are used to make and unmake null moves, respectively.

PackedBoard

Commonly a chess board is represented by a FEN string, but it can also be represented by a PackedBoard. A PackedBoard only uses 24 bytes to represent the board, which is more memory-efficient than a FEN string. The Compact class provides functions to convert a Board object to a PackedBoard and vice versa.

INFO

The PackedBoard is not human-readable, and it is recommended to use the FEN string for debugging purposes.

TIP

Also checkout GameResultReason and GameResult enums.

API

cpp
using PackedBoard = std::array<std::uint8_t, 24>;

class Board {
    public:
        Board::Board(std::string_view fen)

        void setFen(std::string_view fen);
        std::string getFen(bool moveCounters = true);

        /// @brief Make a move on the board. The move must be legal otherwise the
        /// behavior is undefined. EXACT can be set to true to only record
        /// the enpassant square if the enemy can legally capture the pawn on their
        /// next move.
        /// @param move
        /// @tparam EXACT
        /// @return
        void makeMove(const Move move);
        void unmakeMove(const Move move);

        void makeNullMove();
        void unmakeNullMove();

        Bitboard us(Color color);
        Bitboard them(Color color);

        /// @brief recalculate all bitboards
        /// @return
        Bitboard all();

        /// @brief more efficient version of all(), which is incremental
        /// @return
        Bitboard occ();

        Square kingSq(Color color);

        Bitboard pieces(PieceType type, Color color);

        Bitboard pieces(PieceType type);

        /// @brief Checks if a move is a capture, enpassant moves are also considered captures.
        /// @param move
        /// @return
        bool isCapture(const Move move);

        /// @brief Returns either the piece or the piece type on a square
        /// @tparam T
        /// @param sq
        /// @return
        template <typename T = Piece>
        T at(Square sq);

        Color color(Piece piece);

        U64 hash();
        Color sideToMove();
        Square enpassantSq();
        CastlingRights castlingRights();
        int halfMoveClock();
        int fullMoveNumber();

        void set960(bool is960);
        bool chess960();

        std::string getCastleString();

        bool isRepetition(int count = 2);

        /// @brief Checks if the current position is a draw by 50 move rule. Keep in mind
        /// that by the rules of chess, if the position has 50 half moves it's not
        /// necessarily a draw, since checkmate has higher priority, call
        /// getHalfMoveDrawType, to determine whether the position is a draw or
        /// checkmate.
        bool isHalfMoveDraw();

        /// @brief Only call this function if isHalfMoveDraw() returns true.
        std::pair<GameResultReason, GameResult> getHalfMoveDrawType();

        bool isInsufficientMaterial();

        /// @brief Checks if the game is over.
        /// Returns GameResultReason::NONE if the game is not over.
        /// This function calculates all legal moves for the current position
        /// to check if the game is over.
        /// If you are writing you should not use this function.
        std::pair<GameResultReason, GameResult> isGameOver();

        /// @brief Checks if the square is attackeqd by the color.
        bool isAttacked(Square square, Color color);

        /// @brief Check if the current position is in check.
        bool inCheck();

        /// @brief Check if the color has any non pawn material left.
        bool hasNonPawnMaterial(Color color);

        /// @brief Recalculates the zobrist hash and return it.
        /// If you want get the zobrist hash use hash().
        U64 zobrist();

        class Compact {
            public:
                /// @brief Compresses the board into a PackedBoard
                static PackedBoard encode(const Board &board);

                /// @brief Creates a Board object from a PackedBoard
                /// @param compressed
                /// @param chess960 If the board is a chess960 position, set this to true
                static Board decode(const PackedBoard &compressed, bool chess960 = false);
        }
};