Snake and Ladder is a classic turn-based board game played by two or more players on a grid, typically numbered from 1 to 100. Each player starts at cell 1 and takes turns rolling a dice to determine how many steps to move forward.
The game includes:
The first player to land exactly on the final cell (e.g., cell 100) is declared the winner.
In this chapter, we will explore the low-level design of a snake and ladder game in detail.
Lets start by clarifying the requirements:
Before starting the design, it's important to ask thoughtful questions to uncover hidden assumptions and better define the scope of the system.
Here is an example of how a conversation between the candidate and the interviewer might unfold:
Candidate: Should the game support a standard 10x10 board with 100 cells, or should the board size be configurable?
Interviewer: For this version, let’s stick with the standard 10x10 board.
Candidate: Should the number and positions of snakes and ladders be fixed, or should they be configurable?
Interviewer: They should be configurable. The board should allow us to define the number and positions of snakes and ladders at initialization.
Candidate: How many players should the game support? Should it be limited to two, or should we support multiple players?
Interviewer: The game should support multiple players—at least two, but potentially more. Player turns should rotate in order.
Candidate: How should dice rolls be handled? Should we simulate a dice roll in the code or take it as input?
Interviewer: Let’s simulate dice rolls using random number generation from 1 to 6. No need for user input for the roll itself.
Candidate: What should happen if a player rolls a 6? Should they get another turn?
Interviewer: Yes, if a player rolls a 6, they get an extra turn immediately.
Candidate: Should a player roll exact number to land on cell 100, or can they overshoot and still win?
Interviewer: A player must land exactly on 100 to win. If the roll takes them beyond 100, their turn is skipped.
Candidate: Can multiple players occupy the same square at the same time?
Interviewer: Yes, more than one player can land on the same square. There's no interaction or conflict when this happens—no "bumping" or penalties.
After gathering the details, we can summarize the key system requirements.
After the requirements are clear, lets identify the core entities/objects we will have in our system.
Core entities are the fundamental building blocks of our system. We derive them by analyzing the functional requirements and extracting key nouns and responsibilities that naturally map to object-oriented abstractions such as classes, enums, or interfaces.
Let’s go through the functional requirements and identify the relevant entities:
This clearly suggests the need for a Board
entity that maintains the overall structure and layout of the game. The board should internally manage the mapping of special cells (snakes and ladders) and allow querying for cell transitions.
This indicates two distinct entities: Snake
and Ladder
, each with a start and end position. These entities define how a player's position changes if they land on a particular cell.
This calls for a Player
entity to encapsulate information like the player’s name, ID, and current position on the board.
We need a Dice
entity to simulate random rolls between 1 and 6. The dice logic can also handle special behavior like giving an extra turn for a 6.
This behavior should be managed by a Game
entity that acts as the central controller. It will handle player turns, dice rolls, player movement, snake/ladder transitions, win condition checks, and game state updates.
Board
: Represents the 10x10 grid and manages snakes, ladders, and board navigation.Snake
: Represents a snake with a head (start) and tail (end). If a player lands on the head, they are sent back to the tail.Ladder
: Represents a ladder with a base (start) and top (end). If a player lands at the base, they move up to the top.Player
: Represents a participant in the game, maintaining their current position and identifier (e.g., name or ID).Dice
: Simulates dice rolls with random values between 1 and 6. Can include logic for handling an extra turn on rolling a 6.Game
: Acts as the central controller. Manages game state, player turns, board movement, snake/ladder activation, and win condition.These core entities define the key abstractions of the game and will guide the structure of our low-level design and class diagrams.
GameStatus
Represents the lifecycle state of the game.
NOT_STARTED
: The initial state before the game loop begins.RUNNING
: The state when players are actively taking turns.FINISHED
: The terminal state after a winner has been determined.Player
Encapsulates all relevant information about a player
name: String
: Name or identifier of the player.position: int
: The current position of the player on the board (typically from 1 to 100).Snake
A specific type of BoardEntity that represents a snake. It holds a start and end position.
Ladder
A specific type of BoardEntity that represents a ladder. It holds a start and end position.
Dice
A utility class responsible for simulating a dice roll.
Board
Represents the game board's logic.
BoardEntity
Can be introduced to generalize Snake
and Ladder
Game
The central engine that orchestrates the entire game.
The relationships between classes define the overall architecture and how different components collaborate.
This relationship implies that an object is an integral part of another.
This relationship implies that an object contains other objects, but the contained objects can exist independently.
This is a more general relationship where one class uses another.
This relationship defines a hierarchy between classes.
The Game
class acts as the central entry point. It serves as a Facade, providing a simplified interface (createGame, playGame) that hides the complex interactions between the game, board, players, and dice.
This is the most prominent design pattern used in the system. The Game class uses a nested static Builder class (Game.Builder) to construct Game objects.
The BoardEntity abstract class and its subclasses (Snake, Ladder) implicitly follow the structure of this pattern. The base class constructor handles the common logic of storing start and end positions, while the subclasses' constructors are responsible for the specific validation logic (e.g., start > end for Snake), effectively "filling in" a step of the creation template.
Defines the different states of the game:
NOT_STARTED
: The game is initialized but not yet started.RUNNING
: The game is actively being played.FINISHED
: A player has won the game.Encapsulates the behavior of a dice roll. The dice can be customized with a configurable minimum and maximum value (e.g., 1–6). The roll()
method simulates a random roll.
Represents a player in the game. Each player has a name
and a position
on the board, starting from 0. The position is updated after every move.
BoardEntity
(Abstract Base Class)Represents either a Snake or a Ladder. Each entity has a start and end position, and both subclasses (Snake
and Ladder
) impose validation on these.
Snake
Represents a snake on the board. The head of the snake (start
) must be positioned after the tail (end
), enforcing a downward movement.
Ladder
Represents a ladder on the board. The bottom (start
) must be before the top (end
), enforcing an upward jump.
Represents the game board.
size
: Number of squares (typically 100).snakesAndLadders
: Maps positions that trigger snakes or ladders to their destination square.getFinalPosition()
: Returns the adjusted position after hitting a snake or ladder, if applicable.The main controller class that manages the gameplay loop, player turns, game rules, and winning condition.
play()
MethodControls the game loop:
takeTurn()
MethodHandles the actual gameplay mechanics for each player's move:
Builder
Inner ClassImplements the Builder pattern to construct a game instance in a flexible and readable way. Each component (board, players, dice) must be set before calling build()
.
Demonstrates how to use the Game
class to create and play a full game:
Builder
API.