# Design a Chess Game

• Difficulty Level : Hard
• Last Updated : 30 Sep, 2020

Problem Statement: The problem is to design a Chess Game using Object Oriented Principles.

Solution:
These type of questions are asked in interviews to Judge the Object-Oriented Design skill of a candidate. So, first of all we should think about the classes.

The main classes will be:

1. Spot: A spot represents one block of the 8×8 grid and an optional piece.
2. Piece: The basic building block of the system, every piece will be placed on a spot. Piece class is an abstract class. The extended classes (Pawn, King, Queen, Rook, Knight, Bishop) implements the abstracted operations.
3. Board: Board is an 8×8 set of boxes containing all active chess pieces.
4. Player: Player class represents one of the participants playing the game.
5. Move: Represents a game move, containing the starting and ending spot. The Move class will also keep track of the player who made the move.
6. Game: This class controls the flow of a game. It keeps track of all the game moves, which player has the current turn, and the final result of the game.
7. Let’s look at the details. These codes are self-explanatory. You can have a look at the properties/variables and methods of different classes.

Spot: To represent a cell on the chess board:

 `public` `class` `Spot {``    ``private` `Piece piece;``    ``private` `int` `x;``    ``private` `int` `y;`` ` `    ``public` `Spot(``int` `x, ``int` `y, Piece piece)``    ``{``        ``this``.setPiece(piece);``        ``this``.setX(x);``        ``this``.setY(y);``    ``}`` ` `    ``public` `Piece getPiece()``    ``{``        ``return` `this``.piece;``    ``}`` ` `    ``public` `void` `setPiece(Piece p)``    ``{``        ``this``.piece = p;``    ``}`` ` `    ``public` `int` `getX()``    ``{``        ``return` `this``.x;``    ``}`` ` `    ``public` `void` `setX(``int` `x)``    ``{``        ``this``.x = x;``    ``}`` ` `    ``public` `int` `getY()``    ``{``        ``return` `this``.y;``    ``}`` ` `    ``public` `void` `setY(``int` `y)``    ``{``        ``this``.y = y;``    ``}``}`

Piece: An abstract class to represent common functionality of all chess pieces:

 `public` `abstract` `class` `Piece {`` ` `    ``private` `boolean` `killed = ``false``;``    ``private` `boolean` `white = ``false``;`` ` `    ``public` `Piece(``boolean` `white)``    ``{``        ``this``.setWhite(white);``    ``}`` ` `    ``public` `boolean` `isWhite()``    ``{``        ``return` `this``.white;``    ``}`` ` `    ``public` `void` `setWhite(``boolean` `white)``    ``{``        ``this``.white = white;``    ``}`` ` `    ``public` `boolean` `isKilled()``    ``{``        ``return` `this``.killed;``    ``}`` ` `    ``public` `void` `setKilled(``boolean` `killed)``    ``{``        ``this``.killed = killed;``    ``}`` ` `    ``public` `abstract` `boolean` `canMove(Board board, ``                                 ``Spot start, Spot end);``}`

King: To represent King as a chess piece:

 `public` `class` `King ``extends` `Piece {``    ``private` `boolean` `castlingDone = ``false``;`` ` `    ``public` `King(``boolean` `white)``    ``{``        ``super``(white);``    ``}`` ` `    ``public` `boolean` `isCastlingDone()``    ``{``        ``return` `this``.castlingDone;``    ``}`` ` `    ``public` `void` `setCastlingDone(``boolean` `castlingDone)``    ``{``        ``this``.castlingDone = castlingDone;``    ``}`` ` `    ``@Override``    ``public` `boolean` `canMove(Board board, Spot start, Spot end)``    ``{``        ``// we can't move the piece to a Spot that ``        ``// has a piece of the same color``        ``if` `(end.getPiece().isWhite() == ``this``.isWhite()) {``            ``return` `false``;``        ``}`` ` `        ``int` `x = Math.abs(start.getX() - end.getX());``        ``int` `y = Math.abs(start.getY() - end.getY());``        ``if` `(x + y == ``1``) {``            ``// check if this move will not result in the king``            ``// being attacked if so return true``            ``return` `true``;``        ``}`` ` `        ``return` `this``.isValidCastling(board, start, end);``    ``}`` ` `    ``private` `boolean` `isValidCastling(Board board, ``                                     ``Spot start, Spot end)``    ``{`` ` `        ``if` `(``this``.isCastlingDone()) {``            ``return` `false``;``        ``}`` ` `        ``// Logic for returning true or false``    ``}`` ` `    ``public` `boolean` `isCastlingMove(Spot start, Spot end)``    ``{``        ``// check if the starting and ``        ``// ending position are correct``    ``}``}`

Knight: To represent Knight as a chess piece

 `public` `class` `Knight ``extends` `Piece {``    ``public` `Knight(``boolean` `white)``    ``{``        ``super``(white);``    ``}`` ` `    ``@Override``    ``public` `boolean` `canMove(Board board, Spot start, ``                                            ``Spot end)``    ``{``        ``// we can't move the piece to a spot that has``        ``// a piece of the same colour``        ``if` `(end.getPiece().isWhite() == ``this``.isWhite()) {``            ``return` `false``;``        ``}`` ` `        ``int` `x = Math.abs(start.getX() - end.getX());``        ``int` `y = Math.abs(start.getY() - end.getY());``        ``return` `x * y == ``2``;``    ``}``}`

Similarly, we can create classes for other pieces like Queen, Pawns, Rooks, Bishops etc.

Board: To represent a chess board:

 `public` `class` `Board {``    ``Spot[][] boxes;`` ` `    ``public` `Board()``    ``{``        ``this``.resetBoard();``    ``}`` ` `    ``public` `Spot getBox(``int` `x, ``int` `y)``    ``{`` ` `        ``if` `(x < ``0` `|| x > ``7` `|| y < ``0` `|| y > ``7``) {``            ``throw` `new` `Exception(``"Index out of bound"``);``        ``}`` ` `        ``return` `boxes[x][y];``    ``}`` ` `    ``public` `void` `resetBoard()``    ``{``        ``// initialize white pieces``        ``boxes[``0``][``0``] = ``new` `Spot(``0``, ``0``, ``new` `Rook(``true``));``        ``boxes[``0``][``1``] = ``new` `Spot(``0``, ``1``, ``new` `Knight(``true``));``        ``boxes[``0``][``2``] = ``new` `Spot(``0``, ``2``, ``new` `Bishop(``true``));``        ``//...``        ``boxes[``1``][``0``] = ``new` `Spot(``1``, ``0``, ``new` `Pawn(``true``));``        ``boxes[``1``][``1``] = ``new` `Spot(``1``, ``1``, ``new` `Pawn(``true``));``        ``//...`` ` `        ``// initialize black pieces``        ``boxes[``7``][``0``] = ``new` `Spot(``7``, ``0``, ``new` `Rook(``false``));``        ``boxes[``7``][``1``] = ``new` `Spot(``7``, ``1``, ``new` `Knight(``false``));``        ``boxes[``7``][``2``] = ``new` `Spot(``7``, ``2``, ``new` `Bishop(``false``));``        ``//...``        ``boxes[``6``][``0``] = ``new` `Spot(``6``, ``0``, ``new` `Pawn(``false``));``        ``boxes[``6``][``1``] = ``new` `Spot(``6``, ``1``, ``new` `Pawn(``false``));``        ``//...`` ` `        ``// initialize remaining boxes without any piece``        ``for` `(``int` `i = ``2``; i < ``6``; i++) {``            ``for` `(``int` `j = ``0``; j < ``8``; j++) {``                ``boxes[i][j] = ``new` `Spot(i, j, ``null``);``            ``}``        ``}``    ``}``}`

Player: An abstract class for player, it can be a human or a computer.

 `public` `abstract` `class` `Player {``    ``public` `boolean` `whiteSide;``    ``public` `boolean` `humanPlayer;`` ` `    ``public` `boolean` `isWhiteSide()``    ``{``        ``return` `this``.whiteSide;``    ``}``    ``public` `boolean` `isHumanPlayer()``    ``{``        ``return` `this``.humanPlayer;``    ``}``}`` ` `public` `class` `HumanPlayer ``extends` `Player {`` ` `    ``public` `HumanPlayer(``boolean` `whiteSide)``    ``{``        ``this``.whiteSide = whiteSide;``        ``this``.humanPlayer = ``true``;``    ``}``}`` ` `public` `class` `ComputerPlayer ``extends` `Player {`` ` `    ``public` `ComputerPlayer(``boolean` `whiteSide)``    ``{``        ``this``.whiteSide = whiteSide;``        ``this``.humanPlayer = ``false``;``    ``}``}`

Move: To represent a chess move:

 `public` `class` `Move {``    ``private` `Player player;``    ``private` `Spot start;``    ``private` `Spot end;``    ``private` `Piece pieceMoved;``    ``private` `Piece pieceKilled;``    ``private` `boolean` `castlingMove = ``false``;`` ` `    ``public` `Move(Player player, Spot start, Spot end)``    ``{``        ``this``.player = player;``        ``this``.start = start;``        ``this``.end = end;``        ``this``.pieceMoved = start.getPiece();``    ``}`` ` `    ``public` `boolean` `isCastlingMove()``    ``{``        ``return` `this``.castlingMove;``    ``}`` ` `    ``public` `void` `setCastlingMove(``boolean` `castlingMove)``    ``{``        ``this``.castlingMove = castlingMove;``    ``}``}`

 `public` `enum` `GameStatus {``    ``ACTIVE,``    ``BLACK_WIN,``    ``WHITE_WIN,``    ``FORFEIT,``    ``STALEMATE,``    ``RESIGNATION``}`

Game: To represent a chess game:

 `public` `class` `Game {``    ``private` `Player[] players;``    ``private` `Board board;``    ``private` `Player currentTurn;``    ``private` `GameStatus status;``    ``private` `List movesPlayed;`` ` `    ``private` `void` `initialize(Player p1, Player p2)``    ``{``        ``players[``0``] = p1;``        ``players[``1``] = p2;`` ` `        ``board.resetBoard();`` ` `        ``if` `(p1.isWhiteSide()) {``            ``this``.currentTurn = p1;``        ``}``        ``else` `{``            ``this``.currentTurn = p2;``        ``}`` ` `        ``movesPlayed.clear();``    ``}`` ` `    ``public` `boolean` `isEnd()``    ``{``        ``return` `this``.getStatus() != GameStatus.ACTIVE;``    ``}`` ` `    ``public` `boolean` `getStatus()``    ``{``        ``return` `this``.status;``    ``}`` ` `    ``public` `void` `setStatus(GameStatus status)``    ``{``        ``this``.status = status;``    ``}`` ` `    ``public` `boolean` `playerMove(Player player, ``int` `startX, ``                                ``int` `startY, ``int` `endX, ``int` `endY)``    ``{``        ``Spot startBox = board.getBox(startX, startY);``        ``Spot endBox = board.getBox(startY, endY);``        ``Move move = ``new` `Move(player, startBox, endBox);``        ``return` `this``.makeMove(move, player);``    ``}`` ` `    ``private` `boolean` `makeMove(Move move, Player player)``    ``{``        ``Piece sourcePiece = move.getStart().getPiece();``        ``if` `(sourcePiece == ``null``) {``            ``return` `false``;``        ``}`` ` `        ``// valid player``        ``if` `(player != currentTurn) {``            ``return` `false``;``        ``}`` ` `        ``if` `(sourcePiece.isWhite() != player.isWhiteSide()) {``            ``return` `false``;``        ``}`` ` `        ``// valid move?``        ``if` `(!sourcePiece.canMove(board, move.getStart(), ``                                            ``move.getEnd())) {``            ``return` `false``;``        ``}`` ` `        ``// kill?``        ``Piece destPiece = move.getStart().getPiece();``        ``if` `(destPiece != ``null``) {``            ``destPiece.setKilled(``true``);``            ``move.setPieceKilled(destPiece);``        ``}`` ` `        ``// castling?``        ``if` `(sourcePiece != ``null` `&& sourcePiece ``instanceof` `King``            ``&& sourcePiece.isCastlingMove()) {``            ``move.setCastlingMove(``true``);``        ``}`` ` `        ``// store the move``        ``movesPlayed.add(move);`` ` `        ``// move piece from the stat box to end box``        ``move.getEnd().setPiece(move.getStart().getPiece());``        ``move.getStart.setPiece(``null``);`` ` `        ``if` `(destPiece != ``null` `&& destPiece ``instanceof` `King) {``            ``if` `(player.isWhiteSide()) {``                ``this``.setStatus(GameStatus.WHITE_WIN);``            ``}``            ``else` `{``                ``this``.setStatus(GameStatus.BLACK_WIN);``            ``}``        ``}`` ` `        ``// set the current turn to the other player``        ``if` `(``this``.currentTurn == players[``0``]) {``            ``this``.currentTurn = players[``1``];``        ``}``        ``else` `{``            ``this``.currentTurn = players[``0``];``        ``}`` ` `        ``return` `true``;``    ``}``}`

Reference: http://massivetechinterview.blogspot.com/2015/07/design-chess-game-using-oo-principles.html

My Personal Notes arrow_drop_up