0
0
LLDsystem_design~7 mins

Board and piece hierarchy in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
When designing a board game application, mixing all board and piece logic in one place causes code to become tangled and hard to maintain. Adding new piece types or changing board rules becomes error-prone and slows development.
Solution
Separate the board and pieces into a clear class hierarchy where the board manages the game state and pieces encapsulate their own behavior. Use inheritance or composition so each piece type defines its unique moves and properties, while the board handles placement and game rules.
Architecture
Board
- grid
Piece (base)
Pawn
- move()

This diagram shows the Board class holding the game grid and referencing a base Piece class. Specific piece types like Pawn, Knight, and Bishop inherit from Piece and implement their own move logic.

Trade-offs
✓ Pros
Improves code organization by separating board and piece responsibilities.
Makes it easy to add new piece types without changing board code.
Encapsulates piece-specific behavior, reducing bugs and duplication.
Supports polymorphism so board can treat all pieces uniformly.
✗ Cons
Requires upfront design effort to define clear interfaces.
May add slight complexity for very simple games with few piece types.
Inheritance misuse can lead to rigid hierarchies if not designed carefully.
Use when building board games with multiple piece types and complex move rules, especially if the game will evolve or add new pieces over time.
Avoid if the game has only one piece type or very simple rules where separate classes add unnecessary complexity.
Real World Examples
Chess.com
Uses a piece hierarchy to represent different chess pieces, each with unique move logic, while the board manages piece placement and game state.
Lichess
Separates board and piece logic to allow easy implementation of chess variants by extending piece behaviors.
Hasbro (digital Monopoly)
Uses a board and piece model where pieces represent tokens with specific rules and the board manages property positions.
Code Example
The before code mixes all piece move logic inside one Game class, making it hard to maintain. The after code separates pieces into classes inheriting from a base Piece class, each implementing its own move method. The Board class manages piece placement and delegates move validation to pieces, improving clarity and extensibility.
LLD
### Before: All logic in one class
class Game:
    def __init__(self):
        self.board = [[None]*8 for _ in range(8)]

    def move_pawn(self, from_pos, to_pos):
        # pawn move logic here
        pass

    def move_knight(self, from_pos, to_pos):
        # knight move logic here
        pass

### After: Board and piece hierarchy
class Piece:
    def __init__(self, position):
        self.position = position
    def move(self, new_position, board):
        raise NotImplementedError

class Pawn(Piece):
    def move(self, new_position, board):
        # pawn-specific move logic
        pass

class Knight(Piece):
    def move(self, new_position, board):
        # knight-specific move logic
        pass

class Board:
    def __init__(self):
        self.grid = [[None]*8 for _ in range(8)]

    def place_piece(self, piece, position):
        self.grid[position[0]][position[1]] = piece
        piece.position = position

    def move_piece(self, from_pos, to_pos):
        piece = self.grid[from_pos[0]][from_pos[1]]
        if piece and piece.move(to_pos, self):
            self.grid[to_pos[0]][to_pos[1]] = piece
            self.grid[from_pos[0]][from_pos[1]] = None
            piece.position = to_pos
            return True
        return False
OutputSuccess
Alternatives
Monolithic Game Object
All board and piece logic combined in one class without hierarchy.
Use when: For very simple games with minimal piece types and no plan for extension.
Component-Based Design
Pieces are composed of reusable components instead of inheritance, allowing more flexible behavior combinations.
Use when: When pieces share many behaviors that can be mixed and matched dynamically.
Summary
Separating board and piece logic into a class hierarchy improves code organization and maintainability.
Each piece type encapsulates its own behavior, allowing easy addition of new pieces without changing board code.
This pattern is ideal for complex board games with multiple piece types and evolving rules.