Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object Oriented Design for a Chess game [closed]

Tags:

oop

chess

I am trying to get a feel of how to design and think in an Object Oriented manner and want to get some feedback from the community on this topic. The following is an example of a chess game that I wish to design in an OO manner. This is a very broad design and my focus at this stage is just to identify who is responsible for what messages and how the objects interact each other to simulate the game. Please point out if there are elements of bad design (high coupling, bad cohesion etc.) and how to improve on them.

The Chess game has the following classes

  • Board
  • Player
  • Piece
  • Square
  • ChessGame

The Board is made up of squares and so Board can be made responsible for creating and managing Square objects. Each piece also is on a square so each piece also has a reference to the square it is on. (Does this make sense?). Each piece then is responsible to move itself from one square to another. Player class holds references to all pieces he owns and is also responsible for their creation (Should player create Pieces?) . Player has a method takeTurn which in turn calls a method movePiece which belongs to the piece Class which changes the location of the piece from its current location to another location. Now I am confused on what exactly the Board class must be responsible for. I assumed it was needed to determine the current state of the game and know when the game is over. But when a piece changes it's location how should the board get updated? should it maintain a seperate array of squares on which pieces exist and that gets updates as pieces move?

Also, ChessGame intially creates the Board and player objects who in turn create squares and pieces respectively and start the simulation. Briefly, this might be what the code in ChessGame may look like

Player p1 =new Player();
Player p2 = new Player();

Board b = new Board();

while(b.isGameOver())
{
  p1.takeTurn(); // calls movePiece on the Piece object
  p2.takeTurn();

}

I am unclear on how the state of the board will get updated. Should piece have a reference to board? Where should be the responsibility lie? Who holds what references? Please help me with your inputs and point out problems in this design. I am deliberately not focusing on any algorithms or further details of game play as I am only interested in the design aspect. I hope this community can provide valuable insights.

like image 650
Sid Avatar asked Nov 12 '10 18:11

Sid


People also ask

Which pattern can be used to design a chess game?

Strategy Pattern : The Strategy pattern is known as a behavioural pattern – it's used to manage algorithms, relationships and responsibilities between objects. The main benefit of strategy pattern is to choose the algorithm/behaviour at runtime. Lets try to understand this by implementing this to design the chess game.

How do you close a chess game?

Checkmate. One of the most common ways to end a chess game is by checkmate. This happens when one of the players is threatening the other king and it cannot move to any other squares, cannot be protected by another piece and the checking piece cannot be captured.

What is the object of the game in chess?

Chess is one of the oldest and most popular board games. It is played by two opponents on a checkered board with specially designed pieces of contrasting colours, commonly white and black. The objective of the game is to capture the opponent's king.

How is a chess board oriented?

The correct orientation, as per the chess rules, is with a black square on your left side as facing the chess board. One of the more common mistakes in setting up the chess board is reversing the king and queen chess pieces.


2 Answers

I actually just wrote a full C# implementation of a chess board, pieces, rules, etc. Here's roughly how I modeled it (actual implementation removed since I don't want to take all the fun out of your coding):

public enum PieceType {
    None, Pawn, Knight, Bishop, Rook, Queen, King
}

public enum PieceColor {
    White, Black
}

public struct Piece {
    public PieceType Type { get; set; }
    public PieceColor Color { get; set; }
}

public struct Square {
    public int X { get; set; }
    public int Y { get; set; }

    public static implicit operator Square(string str) {
        // Parses strings like "a1" so you can write "a1" in code instead
        // of new Square(0, 0)
    }
}

public class Board {
    private Piece[,] board;

    public Piece this[Square square] { get; set; }

    public Board Clone() { ... }
}

public class Move {
    public Square From { get; }
    public Square To { get; }
    public Piece PieceMoved { get; }
    public Piece PieceCaptured { get; }
    public PieceType Promotion { get; }
    public string AlgebraicNotation { get; }
}

public class Game {
    public Board Board { get; }
    public IList<Move> Movelist { get; }
    public PieceType Turn { get; set; }
    public Square? DoublePawnPush { get; set; } // Used for tracking valid en passant captures
    public int Halfmoves { get; set; }

    public bool CanWhiteCastleA { get; set; }
    public bool CanWhiteCastleH { get; set; }
    public bool CanBlackCastleA { get; set; }
    public bool CanBlackCastleH { get; set; }
}

public interface IGameRules {
    // ....
}

The basic idea is that Game/Board/etc simply store the state of the game. You can manipulate them to e.g. set up a position, if that's what you want. I have a class that implements my IGameRules interface that is responsible for:

  • Determining what moves are valid, including castling and en passant.
  • Determining if a specific move is valid.
  • Determining when players are in check/checkmate/stalemate.
  • Executing moves.

Separating the rules from the game/board classes also means you can implement variants relatively easily. All methods of the rules interface take a Game object which they can inspect to determine which moves are valid.

Note that I do not store player information on Game. I have a separate class Table that is responsible for storing game metadata such as who was playing, when the game took place, etc.

EDIT: Note that the purpose of this answer isn't really to give you template code you can fill out -- my code actually has a bit more information stored on each item, more methods, etc. The purpose is to guide you towards the goal you're trying to achieve.

like image 114
cdhowie Avatar answered Oct 23 '22 09:10

cdhowie


Here is my idea, for a fairly basic chess game :

class GameBoard {
 IPiece config[8][8];  

 init {
  createAndPlacePieces("Black");
  createAndPlacePieces("White");
  setTurn("Black");

 }

 createAndPlacePieces(color) {
   //generate pieces using a factory method
   //for e.g. config[1][0] = PieceFactory("Pawn",color);
 }

 setTurn(color) {
   turn = color;
 }

 move(fromPt,toPt) {
  if(getPcAt(fromPt).color == turn) {
    toPtHasOppositeColorPiece = getPcAt(toPt) != null && getPcAt(toPt).color != turn;
    possiblePath = getPcAt(fromPt).generatePossiblePath(fromPt,toPt,toPtHasOppositeColorPiece);
   if(possiblePath != NULL) {
      traversePath();
      changeTurn();
   }
  }
 } 

}

Interface IPiece {
  function generatePossiblePath(fromPt,toPt,toPtHasEnemy);
}

class PawnPiece implements IPiece{
  function generatePossiblePath(fromPt,toPt,toPtHasEnemy) {
    return an array of points if such a path is possible
    else return null;
  }
}

class ElephantPiece implements IPiece {....}
like image 6
simplfuzz Avatar answered Oct 23 '22 09:10

simplfuzz