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:
- Spot: A spot represents one block of the 8×8 grid and an optional piece.
- 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.
- Board: Board is an 8×8 set of boxes containing all active chess pieces.
- Player: Player class represents one of the participants playing the game.
- 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.
- 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.
- Game Theory (Normal - form game) | Set 1 (Introduction)
- Design Snake Game
- Number of wins for each player in a series of Rock-Paper-Scissor game
- Predict the winner in Coin Game
- Minimum possible final health of the last monster in a game
- Expectimax Algorithm in Game Theory
- Largest odd divisor Game to check which player wins
- Implementation of Tic-Tac-Toe for 2 person game (User vs. User)
- Design an efficient data structure for given operations
- Design a data structure that supports insert, delete, search and getRandom in constant time
- How to design a tiny URL or URL shortener?
- Efficiently design Insert, Delete and Median queries on a set
- Design a Logistics System
- OOPs | Object Oriented Design
- Design an online book reader system
- Design a Hit Counter
- Types of Models in Object Oriented Modeling and Design
- Design a Queue data structure to get minimum or maximum in O(1) time
- Design a data structure that supports insert, delete, getRandom in O(1) with duplicates
- Design a DFA that accepts a string containing 3 a's and 3 b's
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<Move> 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
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.
Improved By : shutovleonid

