Early Access: 87 spots left.

Claim
Low Level DesignInterview QuestionsDesign Snakes and Ladders

Course content

Design Snakes and Ladders

Easy·Tagsllddesignsnakes-and-laddersgame-designturn-order

Problem Statement

Design the core engine for a Snakes and Ladders game. Players take turns rolling a single die; the first player to land exactly on `boardSize` wins. Rules - The board has positions `0..boardSize`. Every player starts at position `0` (off-board). - A roll of `r` (1..6) moves the current player from `pos` to `pos + r`. - If `pos + r > boardSize` the move would overshoot — the player stays at `pos`, and the turn still rotates to the next player. - After moving, apply at most one ladder (bottom → top) and one snake (head → tail) at the new position. Order: ladder first, then snake. (Real-world games typically have only one of the two on any given square; this rule is a deterministic tiebreaker.) - Reaching `boardSize` exactly ends the game; the moving player is the winner. No further turns are accepted. API contract ```java class SnakesAndLaddersGame { public SnakesAndLaddersGame(int boardSize, List<String> playerIds); // Throws IllegalArgumentException if boardSize < 2 or playerIds is empty. public void addLadder(int bottom, int top); // 0 < bottom < top < boardSize public void addSnake(int head, int tail); // 0 < tail < head < boardSize // Both throw IllegalArgumentException for invalid coordinates. /** The current player rolls. Returns the player's new position after applying overshoot, * ladders, and snakes. Throws IllegalArgumentException for diceRoll outside 1..6. Throws IllegalStateException if the game is already over. / public int rollAndMove(int diceRoll); public int getPosition(String playerId); public String getCurrentPlayer(); // whose turn it is, or null after the game ends public String getWinner(); // null while the game is in progress public boolean isGameOver(); } ``` The validator runs three checks: 1. basic_movement_and_turns — 2-player game on a 30-square board, no snakes or ladders. Player A rolls 5 → position 5; getCurrentPlayer is now B. B rolls 3 → position 3; getCurrentPlayer is now A. Turn order rotates correctly. 2. snakes_and_ladders_apply — adding a ladder 4→25 and a snake 28→10, a player rolling 4 from start lands at 25 (climbed the ladder). A player at 25 rolls 3 (→28) and snakes back to 10. 3. winning_and_overshoot — on a 30-square board, a player at 25 rolling 5 lands exactly on 30 and wins (`isGameOver` true, `getWinner` returns that player). A player at 28 rolling 5 would land on 33 — overshoot — and stays at 28; the turn still rotates. The stub class throws `UnsupportedOperationException` from every method, so it fails every check until you implement it. Starter code and validators are available in Java, Python, and C++.

Examples

Example 1
Input
var g = new SnakesAndLaddersGame(30, List.of("A", "B")); g.rollAndMove(5); g.getPosition("A")
Output
"5"
Why
A starts at 0, rolls 5, lands at 5. Turn rotates to B.
Example 2
Input
g.addLadder(4, 25); g.rollAndMove(4); g.getPosition(currentPlayer)
Output
"25"
Why
Landing on 4 climbs the ladder to 25.
Example 3
Input
g at position 28 rolls 5 (board=30)
Output
"stays at 28; turn rotates to next player"
Why
28 + 5 = 33 > boardSize. Overshoot rule: player does not move.

Constraints

  • Constructor: SnakesAndLaddersGame(int boardSize, List<String> playerIds). boardSize >= 2; playerIds non-empty.
  • addLadder(bottom, top): 0 < bottom < top < boardSize.
  • addSnake(head, tail): 0 < tail < head < boardSize.
  • rollAndMove: diceRoll in 1..6 (throws IllegalArgumentException otherwise); throws IllegalStateException if the game is over.
  • Overshoot rule: if pos + diceRoll > boardSize, the player stays put. Turn still rotates.
  • Apply at most one ladder then at most one snake at the destination (no infinite chains).
  • First player to land exactly on boardSize wins; isGameOver becomes true and getCurrentPlayer returns null.

Hints

Stuck? Reveal a nudge toward the right pattern, one step at a time.

Hint 1
State: an int boardSize, a List<String> players, a Map<String, Integer> positions, an int currentPlayerIndex, a String winner (null while in-progress), and Map<Integer, Integer> snakes + ladders.
Hint 2
rollAndMove: validate diceRoll in 1..6 (throw IllegalArgumentException). Throw IllegalStateException if winner is non-null. Compute newPos = pos + diceRoll. If newPos > boardSize → newPos = pos (overshoot rule).
Hint 3
After computing newPos, apply ladders (if ladders.containsKey(newPos), newPos = ladders.get(newPos)). Then apply snakes (if snakes.containsKey(newPos), newPos = snakes.get(newPos)). Apply each at most once.
Hint 4
If newPos == boardSize, set winner = current player and rotate the turn pointer (or set currentPlayerIndex to a sentinel that makes getCurrentPlayer return null). The simplest: store winner and have getCurrentPlayer return null when winner != null.
Hint 5
Always rotate the turn after a roll, including after an overshoot. Only winning halts the rotation.