Chess Game Using C++ (With Source Code)
Hello, coders. Welcome to the codewithrandom blog. In this article, we will learn how to create a Chess Game using C++ (With Source Code).
What is a Chess game and how to create it in C++?
A Chess game is a 2 player game. It is a program that allows two players to play chess on the computer. It entails generating a virtual chessboard and assigning each player a set of pieces to move around the board in turns. The game follows typical chess principles, such as piece movement, capture of opposing pieces, and the goal of placing the opponent’s king into checkmate.
This project will be created by using the concept of Classes from object oriented programming. The game may be played using either a command-line interface or a graphical user interface, with the latter offering a more aesthetically pleasing and user-friendly experience.
Overall, constructing a chess game in C++ entails coding the game’s rules and logic, utilizing object-oriented programming techniques to produce an efficient and versatile program that can handle a variety of game circumstances and user inputs.
Canteen Management System using C++ (With Source Code)
Overview of the UI:
- Heading and welcome message will be displayed:
Chess Game in C++ Source code:
You can directly use this code by copying it in your IDE to understand the working and then can create it by understanding the project.
#include <iostream> #include <stdlib.h> class GamePiece { public: GamePiece(char PieceColor) : mPieceColor(PieceColor) {} ~GamePiece() {} virtual char GetPiece() = 0; char GetColor() { return mPieceColor; } bool IsLegalMove(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { GamePiece* qpDest = GameBoard[iDestRow][iDestCol]; if ((qpDest == 0) || (mPieceColor != qpDest->GetColor())) { return AreSquaresLegal(iSrcRow, iSrcCol, iDestRow, iDestCol, GameBoard); } return false; } private: virtual bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) = 0; char mPieceColor; }; class PawnPiece : public GamePiece { public: PawnPiece(char PieceColor) : GamePiece(PieceColor) {} ~PawnPiece() {} private: virtual char GetPiece() { return 'P'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { GamePiece* qpDest = GameBoard[iDestRow][iDestCol]; if (qpDest == 0) { // Destination square is unoccupied if (iSrcCol == iDestCol) { if (GetColor() == 'W') { if (iDestRow == iSrcRow + 1) { return true; } } else { if (iDestRow == iSrcRow - 1) { return true; } } } } else { // Dest holds piece of opposite color if ((iSrcCol == iDestCol + 1) || (iSrcCol == iDestCol - 1)) { if (GetColor() == 'W') { if (iDestRow == iSrcRow + 1) { return true; } } else { if (iDestRow == iSrcRow - 1) { return true; } } } } return false; } }; class KnightPiece : public GamePiece { public: KnightPiece(char PieceColor) : GamePiece(PieceColor) {} ~KnightPiece() {} private: virtual char GetPiece() { return 'N'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { // Destination square is unoccupied or occupied by opposite color if ((iSrcCol == iDestCol + 1) || (iSrcCol == iDestCol - 1)) { if ((iSrcRow == iDestRow + 2) || (iSrcRow == iDestRow - 2)) { return true; } } if ((iSrcCol == iDestCol + 2) || (iSrcCol == iDestCol - 2)) { if ((iSrcRow == iDestRow + 1) || (iSrcRow == iDestRow - 1)) { return true; } } return false; } }; class BishopPiece : public GamePiece { public: BishopPiece(char PieceColor) : GamePiece(PieceColor) {} ~BishopPiece() {} private: virtual char GetPiece() { return 'B'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { if ((iDestCol - iSrcCol == iDestRow - iSrcRow) || (iDestCol - iSrcCol == iSrcRow - iDestRow)) { // Make sure that all invervening squares are empty int iRowOffset = (iDestRow - iSrcRow > 0) ? 1 : -1; int iColOffset = (iDestCol - iSrcCol > 0) ? 1 : -1; int iCheckRow; int iCheckCol; for (iCheckRow = iSrcRow + iRowOffset, iCheckCol = iSrcCol + iColOffset; iCheckRow != iDestRow; iCheckRow = iCheckRow + iRowOffset, iCheckCol = iCheckCol + iColOffset) { if (GameBoard[iCheckRow][iCheckCol] != 0) { return false; } } return true; } return false; } }; class RookPiece : public GamePiece { public: RookPiece(char PieceColor) : GamePiece(PieceColor) {} ~RookPiece() {} private: virtual char GetPiece() { return 'R'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { if (iSrcRow == iDestRow) { // Make sure that all invervening squares are empty int iColOffset = (iDestCol - iSrcCol > 0) ? 1 : -1; for (int iCheckCol = iSrcCol + iColOffset; iCheckCol != iDestCol; iCheckCol = iCheckCol + iColOffset) { if (GameBoard[iSrcRow][iCheckCol] != 0) { return false; } } return true; } else if (iDestCol == iSrcCol) { // Make sure that all invervening squares are empty int iRowOffset = (iDestRow - iSrcRow > 0) ? 1 : -1; for (int iCheckRow = iSrcRow + iRowOffset; iCheckRow != iDestRow; iCheckRow = iCheckRow + iRowOffset) { if (GameBoard[iCheckRow][iSrcCol] != 0) { return false; } } return true; } return false; } }; class QueenPiece : public GamePiece { public: QueenPiece(char PieceColor) : GamePiece(PieceColor) {} ~QueenPiece() {} private: virtual char GetPiece() { return 'Q'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { if (iSrcRow == iDestRow) { // Make sure that all invervening squares are empty int iColOffset = (iDestCol - iSrcCol > 0) ? 1 : -1; for (int iCheckCol = iSrcCol + iColOffset; iCheckCol != iDestCol; iCheckCol = iCheckCol + iColOffset) { if (GameBoard[iSrcRow][iCheckCol] != 0) { return false; } } return true; } else if (iDestCol == iSrcCol) { // Make sure that all invervening squares are empty int iRowOffset = (iDestRow - iSrcRow > 0) ? 1 : -1; for (int iCheckRow = iSrcRow + iRowOffset; iCheckRow != iDestRow; iCheckRow = iCheckRow + iRowOffset) { if (GameBoard[iCheckRow][iSrcCol] != 0) { return false; } } return true; } else if ((iDestCol - iSrcCol == iDestRow - iSrcRow) || (iDestCol - iSrcCol == iSrcRow - iDestRow)) { // Make sure that all invervening squares are empty int iRowOffset = (iDestRow - iSrcRow > 0) ? 1 : -1; int iColOffset = (iDestCol - iSrcCol > 0) ? 1 : -1; int iCheckRow; int iCheckCol; for (iCheckRow = iSrcRow + iRowOffset, iCheckCol = iSrcCol + iColOffset; iCheckRow != iDestRow; iCheckRow = iCheckRow + iRowOffset, iCheckCol = iCheckCol + iColOffset) { if (GameBoard[iCheckRow][iCheckCol] != 0) { return false; } } return true; } return false; } }; class KingPiece : public GamePiece { public: KingPiece(char PieceColor) : GamePiece(PieceColor) {} ~KingPiece() {} private: virtual char GetPiece() { return 'K'; } bool AreSquaresLegal(int iSrcRow, int iSrcCol, int iDestRow, int iDestCol, GamePiece* GameBoard[8][8]) { int iRowDelta = iDestRow - iSrcRow; int iColDelta = iDestCol - iSrcCol; if (((iRowDelta >= -1) && (iRowDelta <= 1)) && ((iColDelta >= -1) && (iColDelta <= 1))) { return true; } return false; } }; class CBoard { public: CBoard() { for (int iRow = 0; iRow < 8; ++iRow) { for (int iCol = 0; iCol < 8; ++iCol) { MainGameBoard[iRow][iCol] = 0; } } // Allocate and place black pieces for (int iCol = 0; iCol < 8; ++iCol) { MainGameBoard[6][iCol] = new PawnPiece('B'); } MainGameBoard[7][0] = new RookPiece('B'); MainGameBoard[7][1] = new KnightPiece('B'); MainGameBoard[7][2] = new BishopPiece('B'); MainGameBoard[7][3] = new KingPiece('B'); MainGameBoard[7][4] = new QueenPiece('B'); MainGameBoard[7][5] = new BishopPiece('B'); MainGameBoard[7][6] = new KnightPiece('B'); MainGameBoard[7][7] = new RookPiece('B'); // Allocate and place white pieces for (int iCol = 0; iCol < 8; ++iCol) { MainGameBoard[1][iCol] = new PawnPiece('W'); } MainGameBoard[0][0] = new RookPiece('W'); MainGameBoard[0][1] = new KnightPiece('W'); MainGameBoard[0][2] = new BishopPiece('W'); MainGameBoard[0][3] = new KingPiece('W'); MainGameBoard[0][4] = new QueenPiece('W'); MainGameBoard[0][5] = new BishopPiece('W'); MainGameBoard[0][6] = new KnightPiece('W'); MainGameBoard[0][7] = new RookPiece('W'); } ~CBoard() { for (int iRow = 0; iRow < 8; ++iRow) { for (int iCol = 0; iCol < 8; ++iCol) { delete MainGameBoard[iRow][iCol]; MainGameBoard[iRow][iCol] = 0; } } } void Print() { using namespace std; const int kiSquareWidth = 4; const int kiSquareHeight = 3; for (int iRow = 0; iRow < 8*kiSquareHeight; ++iRow) { int iSquareRow = iRow/kiSquareHeight; // Print side border with numbering if (iRow % 3 == 1) { cout << '-' << (char)('1' + 7 - iSquareRow) << '-'; } else { cout << "---"; } // Print the chess board for (int iCol = 0; iCol < 8*kiSquareWidth; ++iCol) { int iSquareCol = iCol/kiSquareWidth; if (((iRow % 3) == 1) && ((iCol % 4) == 1 || (iCol % 4) == 2) && MainGameBoard[7-iSquareRow][iSquareCol] != 0) { if ((iCol % 4) == 1) { cout << MainGameBoard[7-iSquareRow][iSquareCol]->GetColor(); } else { cout << MainGameBoard[7-iSquareRow][iSquareCol]->GetPiece(); } } else { if ((iSquareRow + iSquareCol) % 2 == 1) { cout << '*'; } else { cout << ' '; } } } cout << endl; } // Print the bottom border with numbers for (int iRow = 0; iRow < kiSquareHeight; ++iRow) { if (iRow % 3 == 1) { cout << "---"; for (int iCol = 0; iCol < 8*kiSquareWidth; ++iCol) { int iSquareCol = iCol/kiSquareWidth; if ((iCol % 4) == 1) { cout << (iSquareCol + 1); } else { cout << '-'; } } cout << endl; } else { for (int iCol = 1; iCol < 9*kiSquareWidth; ++iCol) { cout << '-'; } cout << endl; } } } bool IsInCheck(char PieceColor) { // Find the king int iKingRow; int iKingCol; for (int iRow = 0; iRow < 8; ++iRow) { for (int iCol = 0; iCol < 8; ++iCol) { if (MainGameBoard[iRow][iCol] != 0) { if (MainGameBoard[iRow][iCol]->GetColor() == PieceColor) { if (MainGameBoard[iRow][iCol]->GetPiece() == 'K') { iKingRow = iRow; iKingCol = iCol; } } } } } // Run through the opponent's pieces and see if any can take the king for (int iRow = 0; iRow < 8; ++iRow) { for (int iCol = 0; iCol < 8; ++iCol) { if (MainGameBoard[iRow][iCol] != 0) { if (MainGameBoard[iRow][iCol]->GetColor() != PieceColor) { if (MainGameBoard[iRow][iCol]->IsLegalMove(iRow, iCol, iKingRow, iKingCol, MainGameBoard)) { return true; } } } } } return false; } bool CanMove(char PieceColor) { // Run through all pieces for (int iRow = 0; iRow < 8; ++iRow) { for (int iCol = 0; iCol < 8; ++iCol) { if (MainGameBoard[iRow][iCol] != 0) { // If it is a piece of the current player, see if it has a legal move if (MainGameBoard[iRow][iCol]->GetColor() == PieceColor) { for (int iMoveRow = 0; iMoveRow < 8; ++iMoveRow) { for (int iMoveCol = 0; iMoveCol < 8; ++iMoveCol) { if (MainGameBoard[iRow][iCol]->IsLegalMove(iRow, iCol, iMoveRow, iMoveCol, MainGameBoard)) { // Make move and check whether king is in check GamePiece* qpTemp = MainGameBoard[iMoveRow][iMoveCol]; MainGameBoard[iMoveRow][iMoveCol] = MainGameBoard[iRow][iCol]; MainGameBoard[iRow][iCol] = 0; bool bCanMove = !IsInCheck(PieceColor); // Undo the move MainGameBoard[iRow][iCol] = MainGameBoard[iMoveRow][iMoveCol]; MainGameBoard[iMoveRow][iMoveCol] = qpTemp; if (bCanMove) { return true; } } } } } } } } return false; } GamePiece* MainGameBoard[8][8]; }; class ChessBoard { public: ChessBoard() : mcPlayerTurn('W') {} ~ChessBoard() {} void Start() { do { GetNextMove(mqGameBoard.MainGameBoard); AlternateTurn(); } while (!IsGameOver()); mqGameBoard.Print(); } void GetNextMove(GamePiece* GameBoard[8][8]) { using namespace std; bool bValidMove = false; do { system ("clear"); cout<<endl<<endl<<" Welcome to Chess Game Developed by Cppsecrets "<<endl<<endl<<endl; cout<<" Keys to sysmbols used "<<endl<<endl<<endl; cout<<" * = white space"<<endl; cout<<" Blank space = black space"<<endl; cout<<" WP = White pawn & BP = Black pawn"<<endl; cout<<" WN = White Knight & BN = Black Knight"<<endl; cout<<" WB = White Bishop & BB = Black Bishop"<<endl; cout<<" WR = White Rook & BR = Black Rook"<<endl; cout<<" WQ = White Queen & BQ = Black Queen"<<endl; cout<<" WK = White King & BK =Black King"<<endl; cout<<"Rule for move is :"<<endl; cout<<"Move by selecting row & column to another valid location using row & column"<<endl<<endl<<endl; mqGameBoard.Print(); // Get input and convert to coordinates cout << mcPlayerTurn << "'s Move: "; int iStartMove; cin >> iStartMove; int iStartRow = (iStartMove / 10) - 1; int iStartCol = (iStartMove % 10) - 1; cout << "To: "; int iEndMove; cin >> iEndMove; int iEndRow = (iEndMove / 10) - 1; int iEndCol = (iEndMove % 10) - 1; // Check that the indices are in range // and that the source and destination are different if ((iStartRow >= 0 && iStartRow <= 7) && (iStartCol >= 0 && iStartCol <= 7) && (iEndRow >= 0 && iEndRow <= 7) && (iEndCol >= 0 && iEndCol <= 7)) { // Additional checks in here GamePiece* qpCurrPiece = GameBoard[iStartRow][iStartCol]; // Check that the piece is the correct color if ((qpCurrPiece != 0) && (qpCurrPiece->GetColor() == mcPlayerTurn)) { // Check that the destination is a valid destination if (qpCurrPiece->IsLegalMove(iStartRow, iStartCol, iEndRow, iEndCol, GameBoard)) { // Make the move GamePiece* qpTemp = GameBoard[iEndRow][iEndCol]; GameBoard[iEndRow][iEndCol] = GameBoard[iStartRow][iStartCol]; GameBoard[iStartRow][iStartCol] = 0; // Make sure that the current player is not in check if (!mqGameBoard.IsInCheck(mcPlayerTurn)) { delete qpTemp; bValidMove = true; } else { // Undo the last move GameBoard[iStartRow][iStartCol] = GameBoard[iEndRow][iEndCol]; GameBoard[iEndRow][iEndCol] = qpTemp; } } } } if (!bValidMove) { cout << "Invalid Move!" << endl; } } while (!bValidMove); } void AlternateTurn() { mcPlayerTurn = (mcPlayerTurn == 'W') ? 'B' : 'W'; } bool IsGameOver() { // Check that the current player can move // If not, we have a stalemate or checkmate bool bCanMove(false); bCanMove = mqGameBoard.CanMove(mcPlayerTurn); if (!bCanMove) { if (mqGameBoard.IsInCheck(mcPlayerTurn)) { AlternateTurn(); std::cout << "Checkmate, " << mcPlayerTurn << " Wins!" << std::endl; } else { std::cout << "Stalemate!" << std::endl; } } return !bCanMove; } private: CBoard mqGameBoard; char mcPlayerTurn; }; int main() { ChessBoard qGame; qGame.Start(); return 0; }
Now let us understand the code:-
- We will start by writing the header of the code with the required libraries – iostream (input and output stream), stdlib.h (memory management).
- The classes we will be creating for this project are as follows – GamePiece, PawnPiece, KnightPiece, BishopPiece, RookPiece, QueenPiece
- The GamePiece class will contain the common data and functions which will be shared by all the pieces in the game. We will create a constructor for this class and it will take a char parameter PieceColor and will initialize the member variable mPieceColor. We will create a virtual function in this class called GetPiece() that returns a char representing the type of the piece. We will create boolean function IsLegalMove() which will take the source and destination positions of a move, and a pointer to a two-dimensional array GameBoard representing the current state of the game. The function checks if the move is legal and returns a boolean value indicating whether the move is legal or not.
- The derived classes from the base class – GamePiece will override the GetPiece() function and then return the corresponding character for each piece type. The use the if-else control statements.
- For the class PawnPiece, the if-else statement is used to choose between if the Destination square is unoccupied else the destination holds a piece of opposite color.
- For the knightPiece class, the nested if statement is used to see if the destination square is unoccupied or occupied by opposite color.
- For the BishopPiece class, we will make sure that all intervening squares are empty, we will check rows, columns and destination row.
- Similarly for all the pieces we will define their functionality, how they will reach their destination by moving according to their specified rules.
- In the class CBoard, we will allocate and place black pieces by using a for loop and also we will allocate and place white pieces. We will allocate different pieces to their positions on the chess board.
- The Print() function will print out a representation of the chess board on the console. It will basically use two constants kiSquareWidth and kiSquareHeight to determine the width and height of each square on the board. It iterates across the board’s rows and columns, printing out the relevant characters to represent the border, numbering, and chess pieces.
- The boolean type, IsInCheck() function takes a PieceColor parameter (either ‘w’ or ‘b’) and determines if the king of that color is now under control. It goes around the board, checking if any of the opponent’s pieces may lawfully move to the square housing the king. If this is the case, it returns true. If not, it returns false.
- The boolean type, CanMove() function will examine a PieceColor parameter to see if any of the pieces of that color have a valid move on the current board. It will cycle around each square on the board and check for any legal moves that will not place the king of that color in check for each piece of that colour. It will return true if such a move exists. If not, it returns false.
- We will create a class Chessboard which will display the board to play the chess game on. Creating a start() function to start the game using a do/while loop. Creating a GetNextMove() function, clear the screen and then display a welcome message along with keys to symbols used in the game to play. We will get the input and the convert to coordinates.
- After that we will check that the indices are in range and that the source and destination are different. We will use if statements for additional checks for the piece color and valid destination and then make the move.
- The boolean type, IsGameOver() function will check it the current player can move, we have a stalemate or checkmate. And the game will be over.
- The main() function calls the start(0 function to start the chess game.
- This sums up our project of Chess Game using C++.
Cinema Booking System using C++ (With Source Code )
final Output:-
Here is an example to show how this project works.
Conclusion
We have reached the end of this article and have a lot more projects in C++ coming so stay tuned. We have started with awesome and fun projects for you all to understand C++. Learning C++ by creating fun projects makes learning easy and interesting.
Shop Billing System using C++ (With Source Code)
If you enjoyed the article and learned something new today, let us know in the comments.
Thank you.
Happy Reading! 🙂
Follow: CodeWithRandom