chessmcu/inc/Piece.hpp
A.M. Rowsell fa9d534e94
docs: bringing in doxygen-awesome-css, added more inline documentation
The doxygen-awesome-css project is just a nice, simple, customizable
CSS system for making doxygen look less like 1992 and more like
2022. I need to spend a bunch of time tweaking it to make it
look good, and perhaps match it to the style already used at
chess.frzn.dev.

Added more inline Doxycomments, and also generated an image that
represents the logical layout of the boardGrid member variable,
showing the mirrored layout. This works well for our project
because of the way the serial data comes in.
2025-09-16 03:21:53 -04:00

235 lines
6.3 KiB
C++

// © 2025 A.M. Rowsell <amr@frzn.dev>
// 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 <cstdint>
#include <algorithm>
#include <utility>
#include <string>
#include <memory>
#include <vector>
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<Move> getLegalMoves(const Square &from, Board &board) const;
bool finalMoveChecks(std::vector<Move> *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<Move> 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<Move> 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<Move> 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<Move> 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<Move> 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<Move> 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