Design a Chess Game

Problem Design the classes and data structures that represent a chessboard and the pieces on it, sufficient to query the board state and move a piece legally.

Requirements

  • Board.getPiece(square) -> Piece? — what occupies a square
  • Board.movePiece(from: Square, to: Square) -> MoveResult — validate against the piece's rules and current board state, then apply
  • Piece.getLegalMoves(from: Square, board: Board) -> List<Square>
  • Board.isOccupied(square) -> bool and Board.reset() to the starting position

Core design

  • Board is an 8x8 grid of Square/Cell objects, each optionally holding a Piece. Squares are addressable by file/rank so the model reads like the domain rather than raw array indices.
  • Piece as a base class or interface with colour and position; King, Queen, Rook, Bishop, Knight, Pawn each own their legal-move generation. The alternative — one Piece class with a type enum and a switch — is simpler to serialize but centralizes rules and grows a branch per piece type.
  • Move generation splits naturally into sliders (queen, rook, bishop — walk a direction vector until blocked or off-board) and steppers (king, knight — a fixed offset set), so direction vectors can be shared instead of duplicated per class.
  • movePiece validates in order: source has a piece, it is that piece's move shape, the path is clear, the destination is not own-colour. Then it applies and returns a result describing capture/promotion.
  • Pawns are the awkward case worth calling out: direction depends on colour, they capture differently from how they advance, and they have a two-square first move.

Discussion points

  • Where do rules live? Piece-owned generation is open to extension; a central rules engine handles cross-piece rules (en passant, castling) more cleanly. Most designs end up hybrid.
  • Board representation trade-off: an object grid is readable and interview-friendly; bitboards are what real engines use for speed, at the cost of legibility.
  • Square occupancy as null vs. a null-object EmptyPiece — the latter removes null checks from move generation at the cost of an extra type.
  • Concurrency is usually irrelevant for a single game, but matters if the board is shared by a server handling many matches — discuss making Board immutable and returning a new board per move.
  • Extension path: layering check/checkmate detection, move history, and undo on top of this representation.
asked …
LeaderboardSalaryAccount