Facebook Pixel

Design Snake and Ladder

Snake and Ladder is another game problem, a different flavor from tic-tac-toe: a fixed board encodes the rules, a deterministic event (the dice value) drives state forward, and multiple players share a single game object. Because the board is immutable after setup and the rules are self-contained, the design separates cleanly into a board that knows where snakes and ladders are, players that track position, and a game that sequences turns and delegates outcome decisions to the board.

See It in Action

The demo below runs the finished design on a 1–100 board: roll the die to advance the token, climb ladders, slide down snakes, and win by landing exactly on 100. A roll that would overshoot 100 leaves the token where it is. The rest of the article builds exactly this behavior.

Snake and Ladder

Clarifying Requirements

A few questions about "design a Snake and Ladder game" fix the board and the turn order before any code. Functional requirements we commit to: the board runs from 1 to 100; before any rolls, players are placed at position 0 (off the board) and advance from there; the dice value is supplied by the caller rather than randomly generated, so the game is deterministic and testable; any number of players cycle through turns in order; landing on a snake head slides the player to its tail (a lower square); landing on a ladder bottom climbs the player to its top (a higher square); if a roll would push a player past 100, the player stays put rather than moving; and landing exactly on 100 ends the game with that player declared the winner.

The decision flow for a single roll:

Core Entities

Scanning the requirements for the nouns that carry state or enforce rules gives four candidates. Two of them — "snake" and "ladder" — are tempting to promote to classes. Before reading on, decide how a snake or a ladder should be represented: as its own object, or as something simpler on the Board.

Decision checkpoint

1)

A snake connects a head square to a tail square; a ladder connects a bottom to a top. Should each snake and ladder be its own class, or modeled some other way?

A Board holds two maps: snake-head to tail, and ladder-bottom to top. After setup these maps are read-only. The Board's apply method is the single entry point for rule lookup — callers hand it a position and receive the final position plus a modifier tag.

A Player carries an id (1..n) and a current position on the board (0 at the start). It is a plain data holder; it does not decide anything about its own movement.

A Game orchestrates turns. It holds the board, the list of players, and a turn index pointing to whichever player moves next. It cycles that index after every roll and delegates all board questions to Board.

Designing the Classes

Board

Board's job is to answer one question: "if I land on square N, where do I end up and what happened?" Two dictionaries capture all that knowledge — snakes mapping each head to its tail, and ladders mapping each bottom to its top. The apply method checks snakes first, then ladders, then returns the original position unchanged if neither applies. It also returns a modifier string (" (snake)", " (ladder)", or "") so the caller can produce the right output line without needing to know which map was checked.

apply queries both maps in O(1). The setup methods add_snake and add_ladder accept individual entries rather than a batch so the caller can add snakes and ladders incrementally, matching the command-driven test protocol.

A Player holds a position, so it is tempting to give it a move(value) method. But a move depends on the overshoot rule, the board's snakes and ladders, and the turn order — none of which the Player knows. Before reading on, decide where the movement logic belongs.

Decision checkpoint

1)

Resolving a roll involves the overshoot-past-100 rule, the snake/ladder lookup, and advancing the turn. Should that logic live on Player or on Game?

Player

Player carries its id (1-based) and position (starting at 0). There is no behavior: the Game tells the Player where to go by writing to position directly. Keeping Player as a plain data holder avoids the temptation to put movement logic there — that logic belongs in Game where the turn index and overshoot rule live.

Game

Game orchestrates turns. roll(value) is the single public method:

  1. Read the current player using self.turn as an index.
  2. Compute the tentative new position: player.position + value.
  3. Advance self.turn immediately — it must advance whether the move is an overshoot, a normal move, a snake, or a ladder. Only a win keeps the same turn index, but a finished game produces no further rolls, so it does not matter.
  4. If new_pos > 100, the player stays put and the method returns with the player's current position.
  5. Delegate to board.apply(new_pos) to get the final position and modifier.
  6. Write the final position to the player.
  7. If final_pos == 100, return the win message. Otherwise return the normal move message.

The turn is advanced before the overshoot check because the test expects turn cycling even when a player overshoots. Advancing before writing to player.position is safe because the final write happens only for non-overshoot moves.

Try It Yourself

Implement the classes above so that run_game(instructions) replays a command stream and returns one output line per roll. The commands are:

CommandEffectOutput
players nCreate n players (ids 1..n) at position 0. Turns cycle 1, 2, ... n, 1, ...none
snake head tailRegister a snake from head (higher) to tail (lower)none
ladder bottom topRegister a ladder from bottom (lower) to top (higher)none
roll valueCurrent player advances by value. See rules above.one line

Output format for a roll:

  • Player N -> pos — plain move (including overshoot-stays)
  • Player N -> pos (snake) — player slid down a snake
  • Player N -> pos (ladder) — player climbed a ladder
  • Player N wins! — player reached exactly 100
Invest in Yourself
Your new job is waiting. 83% of people that complete the program get a job offer. Unlock unlimited access to all content and features.
Go Pro