// © 2025 A.M. Rowsell // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is "Incompatible With Secondary Licenses", as // defined by the Mozilla Public License, v. 2.0. #ifndef PIECE_HPP #define PIECE_HPP /** @file Piece.hpp * @brief The header files for the Piece class. * * This file contains not only the definition of the Piece class itself, but also all * of the derived classes (King, Queen, Rook, etc.) I was considering having them be in * separate files, but each derived class does not contain that much code, so keeping them * all in one place seemed easier to deal with. This may change in the future! * * Also defined here are important enums that help abstract chess terms, for example the * PieceType, PieceColour, Rank, File, etc. These allow the code to be more readable and * it helps make it obvious what certain bits of code are doing. */ #include #include #include #include #include #include #include "Board.hpp" class Board; enum PieceType { PAWN, BISHOP, KNIGHT, ROOK, QUEEN, KING, EMPTY }; enum PieceColour { PIECE_WHITE, PIECE_BLACK, PIECE_EMPTY }; enum Rank { R1 = 0, R2 = 1, R3 = 2, R4 = 3, R5 = 4, R6 = 5, R7 = 6, R8 = 7, INVALID_RANK = 255 }; enum File { A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, INVALID_FILE = 255 }; enum CastleSide { KINGSIDE = 1, QUEENSIDE = 2 }; /** @struct Square * A struct that represents a square on the chess board. */ struct Square { Rank rank; /**< enum Rank rank represents the rank of the Square */ File file; /**< enum File file represents the file of the Square */ /** * A function to test if the square is a valid square on the chessboard * @return True if the square is within the chessboard, False otherwise */ bool isValid() const { return rank >= 0 && rank < 8 && file >= 0 && file < 8; } }; /** * A struct representing the start and end squares of a Move. */ struct Move { Square from; Square to; }; /** * @class Piece Piece.hpp "inc/Piece.hpp" * @brief A class abstracting chess pieces * * This is a polymorphic base class containing the basic properties all chess pieces have. * It is intended to be extended by a child class for each piece Type, i.e. King, Queen, etc. */ class Piece { private: friend class Board; protected: PieceColour colour; PieceType pieceType; std::string pieceName; /**< std::string pieceName is a string showing the full name of the piece, i.e. "PAWN" */ std::string pieceSymbol; /**< std::string pieceSymbol is a single character, using the standard algebraic chess notation, ie N for Knight */ bool hasMoved = false; public: Piece(PieceColour pColour) : colour(pColour) { } virtual ~Piece(); PieceColour getColour() const { return colour; } std::string getPieceName() const { return pieceName; } std::string getPieceSymbol() const { return pieceSymbol; } PieceType getPieceType() const { return pieceType; } bool checkIfMoved() const { return hasMoved; } /** * A virtual const function that should get all legal moves for a piece, but it may * include some moves that need to be pruned, like those exposing the king to check. * Still working out how to handle this. * * @param from the Square the Piece is currently on * @param board A reference to the Board we are analyzing * @return std::vector of Move: a list of all potentially legal moves */ virtual std::vector getLegalMoves(const Square &from, Board &board) const; bool finalMoveChecks(std::vector *moveList, Board &board); }; class King : public Piece { private: friend class Board; public: King(PieceColour colour) : Piece(colour) { pieceName = "King"; pieceSymbol = "K"; pieceType = KING; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; bool checkForCheck(Board &board) const; bool checkForCastle(enum CastleSide side) const { if(side == KINGSIDE) return canCastleKS; else if(side == QUEENSIDE) return canCastleQS; else return false; } void setCastleQS(bool canCastle) { canCastleQS = canCastle; } void setCastleKS(bool canCastle) { canCastleKS = canCastle; } protected: bool canCastleQS = true; bool canCastleKS = true; bool inCheck = false; }; class Rook : public Piece { friend class Board; public: Rook(PieceColour colour) : Piece(colour) { pieceName = "Rook"; pieceSymbol = "R"; pieceType = ROOK; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; }; class Queen : public Piece { friend class Board; public: Queen(PieceColour colour) : Piece(colour) { pieceName = "Queen"; pieceSymbol = "Q"; pieceType = QUEEN; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; }; class Knight : public Piece { friend class Board; public: Knight(PieceColour colour) : Piece(colour) { pieceName = "Knight"; pieceSymbol = "N"; pieceType = KNIGHT; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; }; class Bishop : public Piece { friend class Board; public: Bishop(PieceColour colour) : Piece(colour) { pieceName = "Bishop"; pieceSymbol = "B"; pieceType = BISHOP; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; }; class Pawn : public Piece { friend class Board; public: Pawn(PieceColour colour) : Piece(colour) { pieceName = "Pawn"; pieceSymbol = "P"; pieceType = PAWN; } virtual std::vector getLegalMoves(const Square &from, Board &board) const override; void promote(const Square &promotionSquare, Board &board, PieceType promoteTo); protected: bool vulnEnPassant = false; bool firstMove = true; }; #endif // PIECE_HPP