///////////////////////////////////////////////////////////////////////////// // // TpmChess.h : interface for Chess classes // // Written by Thomas F. Mooney, III (tfm3@teleproc.com) // Copyright © 1999. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name is included. If // the source code in this file is used in any commercial application // then acknowledgement must be made to the author of this file // (in whatever form you wish). // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability if it causes any damage to your // computer, data, etc. // // Please report any bugs/anomalies/suggestions to the author via the // e-mail address listed above. // ///////////////////////////////////////////////////////////////////////////// #if !defined(TpmChess_h_) #define TpmChess_h_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 ///////////////////////////////////////////////////////////////////////////// // This file contains the declaration of several classes that // are used to simulate a game of chess. // // The classes include: // ChessMove - a single move // ChessMan - a pawn or piece - used to subclass // ChessPawn - pawn // ChessKnight - knight // ChessBishop - bishop // ChessRook - rook // ChessQueen - queen // ChessKing - king // ChessSquare - a single square on a chess board // ChessBoard - a collection of squares and men // includes game status ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "ChessTypes.h" enum ChessManType // types of men in a chess game { Pawn, Knight, Bishop, Rook, Queen, King }; class ChessSquare; class ChessMove // information that represents a single move { friend class ChessBoard; public: ChessMove(); ChessMove(const ChessMove& OldMove); ~ChessMove(); ChessMove& operator=(const ChessMove& OldMove); bool operator<(ChessMove& HigherMove); void ParseSAN(SAN San); SAN CreateSAN(); bool IsLegalMove(); std::string GetErrorMsg(); bool IsMoveAltered(); ChessManType GetManToMove(); bool IsCapture(); std::string GetEnPassantTarget(); EPD GetPiecePlacementAfter(); std::string GetCastleAvailabilityAfter(); void SetLastInPv(bool Last); protected: private: void ResetDefaults(); public: protected: ChessManType m_ManToMove; // type of man char m_cSourceFile; // source square char m_cSourceRank; char m_cTargetFile; // target square char m_cTargetRank; char m_cDisambigFile; // used for disambiguation char m_cDisambigRank; bool m_bCapture; // is this a capture bool m_bCheck; // does it produce check bool m_bCheckmate; // does it produce checkmate bool m_bPromote; // is it a pawn promotion bool m_bCastleKingside; // do we castle kingside bool m_bCastleQueenside; // do we castle queenside ChessManType m_PromoteTo; // what do we promote to std::string m_EnPassantTarget; // what is the en passant target // after playing this move std::string m_PiecePlacementAfter; // what does the board look like std::string m_CastleAvailabilityAfter; // after playing this move bool m_bLegalMove; // is the move legal std::string m_ErrorMessage; // if not, why not bool m_bMoveAltered; // did we alter the move to play it // this means we achieved check or mate // but the move did not specify this bool m_bLastInPv; // last move in PV, do checkmate analysis private: }; typedef std::list MOVE_LIST; // to collect moves class ChessMan // information that represents a { friend class ChessBoard; friend class ChessSquare; // single pawn or piece on the board public: // pure virtual, must be subclassed ChessMan(); ChessMan(ChessMan& OldMan); virtual ~ChessMan(); ChessMan& operator=(ChessMan& OldMan); void SetType(ChessManType Type); ChessManType GetType(); void SetColorWhite(bool White); bool IsColorWhite(); void SetValue(float Value); float GetValue(); void SetSquare(ChessSquare* pSquare); ChessSquare* GetSquare(); ChessBoard* GetBoard(); char GetFile(); char GetRank(); void Capture(); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture) = 0; protected: private: public: protected: ChessManType m_Type; // indicates type (pawn, knight...) bool m_bWhite; // white=true, black=false float m_Value; // pawn=1, bishop=3, etc. ChessSquare* m_pSquare; // square this man is on private: }; class ChessPawn : public ChessMan { public: ChessPawn(); ChessPawn(ChessPawn& OldPawn); ~ChessPawn(); ChessPawn& operator=(ChessPawn& OldPawn); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessKnight : public ChessMan { public: ChessKnight(); ChessKnight(ChessKnight& OldKnight); ~ChessKnight(); ChessKnight& operator=(ChessKnight& OldKnight); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessBishop : public ChessMan { public: ChessBishop(); ChessBishop(ChessBishop& OldBishop); ~ChessBishop(); ChessBishop& operator=(ChessBishop& OldBishop); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessRook : public ChessMan { public: ChessRook(); ChessRook(ChessRook& OldRook); ~ChessRook(); ChessRook& operator=(ChessRook& OldRook); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessQueen : public ChessMan { public: ChessQueen(); ChessQueen(ChessQueen& OldQueen); ~ChessQueen(); ChessQueen& operator=(ChessQueen& OldQueen); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessKing : public ChessMan { public: ChessKing(); ChessKing(ChessKing& OldKing); ~ChessKing(); ChessKing& operator=(ChessKing& OldKing); virtual bool CanMoveTo(char TargetFile, char TargetRank, bool Capture); protected: private: public: protected: private: }; class ChessSquare // information that represents a { // single square on a chess board friend class ChessBoard; friend class ChessMan; friend class ChessPawn; friend class ChessKnight; friend class ChessBishop; friend class ChessRook; friend class ChessQueen; friend class ChessKing; public: ChessSquare(); ChessSquare(ChessSquare& OldSquare); ~ChessSquare(); ChessSquare& operator=(ChessSquare& OldSquare); void SetColorLight(bool Light); bool IsColorLight(); void SetFile(char File); char GetFile(); void SetRank(char Rank); char GetRank(); std::string GetID(); void SetBoard(ChessBoard* pBoard); ChessBoard* GetBoard(); void SetOccupant(ChessMan* pChessMan); inline ChessMan* GetOccupant(){return m_pOccupant;}; void ResetAttack(); void UpdateAttack(bool ByWhite, float AttackValue); int GetAttackCount(bool ByWhite); float GetAttackValue(bool ByWhite); void AddPiece(ChessMan* pChessMan); void RemovePiece(); void PickUpPiece(); void SetDownPiece(ChessMan* pChessMan); void ClearSquare(); inline ChessSquare* GetFileUp(){return m_pFileUp;}; inline ChessSquare* GetFileDown(){return m_pFileDown;}; inline ChessSquare* GetRankRight(){return m_pRankRight;}; inline ChessSquare* GetRankLeft(){return m_pRankLeft;}; inline ChessSquare* GetDiagUpRight(){return m_pDiagUpRight;}; inline ChessSquare* GetDiagUpLeft(){return m_pDiagUpLeft;}; inline ChessSquare* GetDiagDownRight(){return m_pDiagDownRight;}; inline ChessSquare* GetDiagDownLeft(){return m_pDiagDownLeft;}; protected: private: public: protected: bool m_bLight; // light=true, dark=false char m_File; // file on the board a-h char m_Rank; // rank on the board 1-8 bool m_bAttackAnalyzed; // indicates attack is analyzed int m_AttackCount[2]; // number of pieces attacking float m_AttackValue[2]; // value of pieces attacking ChessBoard* m_pBoard; // points to board ChessSquare* m_pFileUp; // same file, higher rank ChessSquare* m_pFileDown; // same file, lower rank ChessSquare* m_pRankRight; // same rank, higher file ChessSquare* m_pRankLeft; // same rank, lower file // diagonals from white players perspective ChessSquare* m_pDiagUpRight; // forward and right ChessSquare* m_pDiagUpLeft; // forward and left ChessSquare* m_pDiagDownRight; // back and right ChessSquare* m_pDiagDownLeft; // back and left ChessMan* m_pOccupant; // points to man on square private: }; const int WHITE = 0; // to distinguish two players const int BLACK = 1; typedef std::list PieceList; // to collect pieces class ChessBoard // information that represents a { // chess board and its game status public: ChessBoard(); ChessBoard(ChessBoard& OldBoard); ~ChessBoard(); ChessBoard& operator=(ChessBoard& OldBoard); void Reset(); ChessSquare* GetSquare(char File, char Rank); ChessSquare* GetSquare(std::string ID); void SetPiecePlacement(EPD Position); void SetWhiteToMove(bool WhiteToMove); void SetBlackToMove(bool BlackToMove); void SetCastleAvailability(std::string CastleAvailability); void SetEnPassantTarget(std::string EnPassantTarget); void SetFullMoveNumber(int FullMove); void SetHalfMoveClock(int HalfMove); void SetPosition(char* Position); void Move(ChessMove& Move); void MovePawn(ChessMove& Move); void MoveKnight(ChessMove& Move); void MoveBishop(ChessMove& Move); void MoveRook(ChessMove& Move); void MoveQueen(ChessMove& Move); void MoveKing(ChessMove& Move); EPD GetPiecePlacement(); char* GetBinaryPosition(); bool IsWhiteToMove(); bool IsBlackToMove(); int GetColorToMove(); std::string GetCastleAvailability(); std::string GetEnPassantTarget(); bool IsEnPassantCapturePossible(); int GetFullMoveNumber(); int GetHalfMoveClock(); void MayCastleKingside(bool MayCastle, int Color); void MayCastleQueenside(bool MayCastle, int Color); bool MayCastleKingside(int Color); bool MayCastleQueenside(int Color); void AddPiece(char File, char Rank, ChessMan* pChessMan); void RemovePiece(char File, char Rank); void ResetAttack(); void AnalyzeAttack(); bool IsKingChecked(int Color); bool ValidateCheckStatus(); bool ValidateEnPassantStatus(); bool ValidatePawnPlacement(); bool ValidateCastleAvailability(); MOVE_LIST GetLegalMoveList(bool Iterate); protected: private: void LinkSquares(); void GetCandidateMoveList(MOVE_LIST& CandidateList); bool AbsolutePinnedPiece(char cSourceFile, char cSourceRank, char cTargetFile, char cTargetRank, bool bCapture, bool bWhite); void CheckCastlingAfterCapture(ChessMove& Move); public: protected: ChessSquare* m_pSquare[FileCount][RankCount]; // square on board PieceList m_PieceList; // pawns/pieces on board bool m_bWhiteToMove; // who moves next, true=white, false=black bool m_bMayCastleKingside[2]; // who may castle kingside bool m_bMayCastleQueenside[2]; // who may castle queenside std::string m_EnPassantTarget; // en passant target int m_nHalfMoveClock; // half moves since last pawn push // or capture int m_nFullMoveNumber; // move number private: bool m_bAttackAnalyzed; // board attack has been analyzed }; #endif // !defined(TpmChess_h_)