# Design a Chess Game

Problem Statement: The problem is to design a Chess Game using Object Oriented Principles. Asked In: Adobe, Amazon, Microsoft, etc. 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

Previous
Next