This document provides a comprehensive and detailed explanation of the Low-Level Design (LLD) of the Chess game implemented in Java. It covers the core requirements, design patterns, class structures, entity relations, and the flow of the game.
- Board: An 8x8 standard chessboard.
- Pieces: 16 pieces for each player (1 King, 1 Queen, 2 Rooks, 2 Bishops, 2 Knights, 8 Pawns).
- Players: Two players (White and Black).
- Moves: Pieces move according to standard chess rules.
- Rules Supported (Core): Basic moves, captures, collision checking (path blocking), turns.
- Rules Deferred (Extensions): Check, Checkmate, Stalemate, Castling, En Passant, Pawn Promotion (partially implemented).
- History: The game must maintain a complete history of all moves.
- State: The game can be Active, Draw, White Win, Black Win, etc.
The design follows classical Object-Oriented Programming (OOP) principles, ensuring high cohesion and low coupling.
Box(Square): Represents a single cell on the board. It holds itsxandycoordinates and maintains a reference to thePiececurrently sitting on it. If empty,pieceisnull.Chessboard: A collection of 64Boxobjects configured as an 8x8 2D array. It is responsible for initializing the board, placing pieces at their default positions viaresetBoard(), and providing utility methods like checking if a path between two boxes is blocked (important for sliding pieces like Queens, Rooks, and Bishops).
The design leverages the Strategy and Template Method patterns implicitly via polymorphism.
Piece(Abstract Class): The base class for all chess pieces. It holds properties likewhite(boolean to indicate color) andkilled(boolean). The core of this class is the abstract methodcanMove(Chessboard board, Box start, Box end).- Every specific piece implements its own movement logic by extending
Pieceand overridingcanMove(). - Classes:
King,Queen,Rook,Knight,Bishop,Pawn. - Example: The
Pawnimplements logic for moving forward, double-stepping from the start line, and capturing diagonally. TheBishoplogic verifies a diagonal path and usesChessboard.isPathBlocked()to ensure no pieces obstruct the path.
- Every specific piece implements its own movement logic by extending
Player: Holds player information (name, color side).Move: Represents a single transaction or turn. It records the startingBox, endingBox, thepieceMoved, thepieceKilled(if a capture happened), thePlayerwho made the move, and theMoveType(Normal, Castling, En Passant). This is crucial for maintaining a log (MoveHistory) and potentially implementing undo functionality.ChessGame: The central controller (Facade) that glues everything together. It contains:Player[]players.Chessboardboard.PlayercurrentTurn.GameStatusstatus (ACTIVE, BLACK_WIN, WHITE_WIN, DRAW, etc.).List<Move>moveHistory.ChessMoveControllercontroller.ChessGameViewview. It manages the game loop (play()), validates inputs, alternates turns, and commits moves.
The code embraces a lightweight Model-View-Controller (MVC) architecture:
- Model:
Chessboard,Box,Piece,Move,GameStatus, etc. - View:
ChessGameViewis responsible for rendering the board state to the console and displaying move information. - Controller:
ChessMoveControlleracts as a service that encapsulates the rule-checking logic. It validates if a proposed move is fundamentally legal before altering the Model.
- Factory Pattern (Implicit): While not purely extracted into a distinct class, the
Chessboard.resetBoard()method acts as a Factory, instantiating the correct concrete classes ofPiecebased on board coordinates. - Command Pattern (Conceptual): The
Moveclass represents the Command pattern. Encapsulating a move as an object allows logging, undo/redo (if implemented), and auditing. - Facade Pattern:
ChessGamesimplifies the interaction between the Client (or Driver) and the complex subsystem (turns, boards, validation, state updates) into a single unified interface. - Strategy Method / Polymorphism: The abstract
canMove()inPieceallows the controller to blindly callvalidateMove()on any piece without knowing its type, adhering to the Open-Closed Principle. - DRY (Don't Repeat Yourself): By moving the target square "capture vs move" validation into a
protectedhelper methodisValidDestination(Box end)inside thePiecebase class, we reduced code duplication across all subclasses. This ensures clean, maintainable code.
- Input Parsing:
ChessGamereceives the input string "e2 e4" and translates algebraic notation into 0-indexed integer coordinates (x: 1, y: 4 to x: 3, y: 4). - Retrieve Entities: The game fetches the starting
Boxand endingBoxfrom theChessboard. - Pre-Validation:
- Ensure the starting
Boxhas a piece. - Ensure the piece belongs to the
currentTurnplayer.
- Ensure the starting
- Rule Validation:
ChessMoveControllerasks the piece:piece.canMove(board, start, end).- The
Pawninherently knows if it's white, it can move +2 steps on its first turn, provided the destination is empty and the path is clear.
- The
- Execution:
- The captured piece (if any) is identified.
- The end
Boxis updated to hold the movingpiece. - The start
Boxis set tonull.
- Logging: A new
Moveobject is instantiated and added tomoveHistory. - Post-Move Logic:
- The turn is switched (
currentTurntoggles). - Base end-game states are checked (e.g., Draw after 50 moves).
- The turn is switched (
- View Update:
ChessGameViewre-renders the board with the updated state.
When discussing this LLD, you can showcase your ability to scale and refine the system by mentioning the following improvements:
- Check and Checkmate Validation: Implement an
isKingInCheck()algorithm that evaluates the board after a tentative move. If the move leaves their own King in check, it's invalid. - Rule Extensibility: Use an explicit Rules Engine or Chain of Responsibility instead of a single
canMovemethod for highly complex scenarios (like Castling requiring king not passing through check). - Undo Strategy: To implement undo, the
Commandpattern (represented by theMoveclass) should have anundo()method that reverses the specific piece movements and restores anypieceKilled. - Concurrency: If adapted for an online multiplayer server,
ChessGamestate mutations would need synchronization (e.g., Read/Write locks orsynchronizedblocks) to avoid race conditions when two players send moves simultaneously.
Summary: This low-level design is highly modular. It cleanly divides state (Board/Boxes), behavior (Pieces/Controller), and execution flow (ChessGame). It perfectly demonstrates SOLID principles and prepares a scalable foundation for a fully rigid Chess ruleset.