LLD Problem
Design Chess Game
Design an object-oriented chess game with proper piece hierarchy, move validation, and game state management.
30 min readAdvanced LLD Problem
1Class Design Overview
Game
- board
- players[]
- currentTurn
- status
+ makeMove()
+ isCheckmate()
+ isStalemate()
Board
- cells[8][8]
- pieces[]
+ getCell()
+ movePiece()
+ isPathClear()
Piece (Abstract)
- color
- position
- hasMoved
+ canMove()
+ getValidMoves()
King
- extends Piece
+ canCastle()
+ isInCheck()
Queen/Rook/Bishop
- extends Piece
+ Specific move logic
Pawn
- extends Piece
+ canPromote()
+ enPassant()
Key Design Decision: Use abstract
Piece class with abstractcanMove(from, to, board) method. Each piece type implements its own movement logic. This follows Template Method and Open/Closed Principle.2Piece Movement Logic
| Piece | Movement Pattern | Special Rules |
|---|---|---|
| King | 1 square any direction | Castling, cannot move into check |
| Queen | Any direction, any distance | Cannot jump over pieces |
| Rook | Horizontal/vertical, any distance | Involved in castling |
| Bishop | Diagonal, any distance | Cannot jump over pieces |
| Knight | L-shape (2+1 or 1+2) | Can jump over pieces |
| Pawn | Forward 1 (or 2 from start) | Capture diagonally, en passant, promotion |
Piece Movement Code Structure
abstract class Piece {
protected Color color;
protected Position position;
protected boolean hasMoved = false;
// Template Method pattern
public boolean canMove(Position to, Board board) {
// Common validations
if (!board.isValidPosition(to)) return false;
if (to.equals(position)) return false;
Cell targetCell = board.getCell(to);
if (targetCell.hasPiece() &&
targetCell.getPiece().getColor() == color) {
return false; // Can't capture own piece
}
// Piece-specific logic
return isValidMove(to, board);
}
protected abstract boolean isValidMove(Position to, Board board);
public abstract List<Position> getValidMoves(Board board);
}
class Knight extends Piece {
@Override
protected boolean isValidMove(Position to, Board board) {
int dx = Math.abs(to.getX() - position.getX());
int dy = Math.abs(to.getY() - position.getY());
return (dx == 2 && dy == 1) || (dx == 1 && dy == 2);
}
}
class Rook extends Piece {
@Override
protected boolean isValidMove(Position to, Board board) {
if (to.getX() != position.getX() && to.getY() != position.getY()) {
return false; // Must be same row or column
}
return board.isPathClear(position, to);
}
}3Special Rules
Castling
- King and Rook haven't moved
- No pieces between them
- King not in check, doesn't pass through check
- King moves 2 squares, Rook jumps over
En Passant
- Pawn moves 2 squares from start
- Opponent's pawn can capture as if it moved 1
- Must capture immediately next turn
- Store last move to check eligibility
Pawn Promotion
- Pawn reaches opposite end
- Must promote to Queen/Rook/Bishop/Knight
- Usually Queen, but not always
- Replace Pawn with chosen piece
Check/Checkmate/Stalemate
- Check: King under attack
- Checkmate: Check + no legal moves
- Stalemate: No legal moves but not in check
- After each move, validate game state
4Interview Follow-up Questions
Interview Follow-up Questions
Common follow-up questions interviewers ask
5Key Takeaways
1Abstract Piece class with piece-specific isValidMove().
2Template Method for common move validation.
3Store hasMoved for castling validation.
4Simulate moves to validate King safety.
5Command Pattern for undo/redo.
6Handle all special rules: castling, en passant, promotion.