236 lines
6.4 KiB
C++
236 lines
6.4 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>
|
|
#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();
|
|
virtual std::vector<Move> getLegalMoves(const Square &from, Board &board) const;
|
|
|
|
PieceColour getColour() const {
|
|
return colour;
|
|
}
|
|
|
|
std::string getPieceName() const {
|
|
return pieceName;
|
|
}
|
|
|
|
char 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
|
|
|