AlgoMaster Logo

Design Snake and Ladder game

Ashish

Ashish Pratap Singh

easy

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:

  • Ladders, which boost progress by instantly moving the player up to a higher cell
  • Snakes, which hinder progress by sliding the player down to a lower cell

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:

1. Clarifying 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:

After gathering the details, we can summarize the key system requirements.

1.1 Functional Requirements

  • The game is played on a standard 10x10 board with 100 numbered cells
  • Support configuration of snakes and ladders with flexible start and end positions
  • Snakes send the player back to a lower-numbered square; ladders move the player forward
  • Allow multiple players (minimum two), with turn rotation in round-robin order
  • Simulate dice rolls with random values between 1 and 6. A player gets an extra turn if they roll a 6
  • A player must roll the exact number to land on cell 100 and win the game
  • Multiple players can occupy the same cell without interaction

1.2 Non-Functional Requirements

  • Modularity: The system should follow object-oriented principles with clean separation between components
  • Extensibility: The design should allow future enhancements such as custom board sizes or different types of dice
  • Maintainability: The codebase should be clean, readable, and easy to extend
  • User Feedback: The system should provide clear console output after each turn, indicating player moves, dice rolls, snake or ladder interactions, and current positions

After the requirements are clear, lets identify the core entities/objects we will have in our system.

2. Identifying Core Entities

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:

1. The game is played on a standard 10x10 board with 100 numbered cells.

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.

2. The board has configurable positions for snakes and ladders.

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.

3. The game supports multiple players who take turns.

This calls for a Player entity to encapsulate information like the player’s name, ID, and current position on the board.

4. Players roll a die, and rolling a 6 gives an extra turn.

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.

5. The game needs to manage turns, apply snakes and ladders, and determine when a player wins.

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.

These core entities define the key abstractions of the game and will guide the structure of our low-level design and class diagrams.

3. Class Design

3.1 Class Definitions

Enums

GameStatus

Represents the lifecycle state of the game.

Enums
  • 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.

Data Classes

Player

Encapsulates all relevant information about a player

Player

Attributes:

  • 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.

Core Classes

Dice

A utility class responsible for simulating a dice roll.

Dice

Board

Represents the game board's logic.

Board

BoardEntity

Can be introduced to generalize Snake and Ladder

Game

The central engine that orchestrates the entire game.

Game

3.2 Class Relationships

The relationships between classes define the overall architecture and how different components collaborate.

Composition (Strong "has-a")

This relationship implies that an object is an integral part of another.

  • Game --* Board: A Game is composed of exactly one Board. The Board's existence is entirely dependent on the Game instance.
  • Game --* Dice: A Game has one Dice. The Dice is created for and owned by the Game.

Aggregation (Weak "has-a")

This relationship implies that an object contains other objects, but the contained objects can exist independently.

  • Game o-- Player: A Game has a collection of Players. This is modeled as aggregation because Players are conceptually separate entities from the game itself, even if their lifecycle in this specific implementation is tied to the game's creation.
  • Board o-- BoardEntity: A Board is configured with a list of BoardEntity objects (snakes and ladders). The entities are created outside the Board and passed to it, so the board uses them but does not control their lifecycle.

Association ("uses-a")

This is a more general relationship where one class uses another.

  • Game --> Queue<Player>: The Game class uses a Queue to manage the turn-based order of players in a First-In, First-Out (FIFO) manner.
  • Board --> Map<Integer, Integer>: The Board uses a Map to efficiently store and look up the start and end points of snakes and ladders.

Inheritance ("is-a")

This relationship defines a hierarchy between classes.

  • Snake --|> BoardEntity: A Snake is a specialized type of BoardEntity.
  • Ladder --|> BoardEntity: A Ladder is also a specialized type of BoardEntity.

3.3 Key Design Patterns

Facade Pattern

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.

Builder Pattern

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.

Template Method Pattern (Implicit)

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.

3.4 Full Class Diagram

4. Implementation

4.1 GameStatus

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.

4.2 Dice

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.

4.3 Player

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.

4.4 Board Entities

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.

4.5 Board

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.

4.6 Game Engine

The main controller class that manages the gameplay loop, player turns, game rules, and winning condition.

play() Method

Controls the game loop:

  • Continues until one player wins.
  • Each player takes a turn in FIFO order.
  • Players who roll a 6 get an extra turn.
  • The game ends when a player reaches the final cell.
takeTurn() Method

Handles the actual gameplay mechanics for each player's move:

  • Rolls the dice.
  • Updates position based on the roll.
  • Applies snake or ladder effects.
  • Checks for win condition.
  • Gives an extra turn for rolling a 6.

Builder Inner Class

Implements 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().

4.7 Game Execution Demo

Demonstrates how to use the Game class to create and play a full game:

  • Defines a list of snakes and ladders.
  • Initializes players.
  • Builds and starts the game using the Builder API.

5. Run and Test

Languages
Loading...
Loading editor...

6. Quiz

Test Your Understanding

Q1.
Question 1 of 0