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 squareBoard.movePiece(from: Square, to: Square) -> MoveResult— validate against the piece's rules and current board state, then applyPiece.getLegalMoves(from: Square, board: Board) -> List<Square>Board.isOccupied(square) -> boolandBoard.reset()to the starting position
Core design
Boardis an 8x8 grid ofSquare/Cellobjects, each optionally holding aPiece. Squares are addressable by file/rank so the model reads like the domain rather than raw array indices.Pieceas a base class or interface with colour and position;King,Queen,Rook,Bishop,Knight,Pawneach own their legal-move generation. The alternative — onePiececlass 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.
movePiecevalidates 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
nullvs. a null-objectEmptyPiece— 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
Boardimmutable and returning a new board per move. - Extension path: layering check/checkmate detection, move history, and undo on top of this representation.
asked …