Design Snake and Ladder (LLD)
1. Requirements
-
Functional
- Board with numbered cells; snakes and ladders connect pairs of cells.
- Two or more players roll dice (or spinner); move forward; land on snake tail slides down, ladder foot climbs up.
- First to reach or pass final cell wins; exact roll requirement configurable.
-
Non-Functional
- Deterministic simulation given dice sequence (testability).
- Pluggable dice source (fair RNG, fixed sequence for tests).
-
Assumptions / Out of Scope
- No monetization or persistence; single match in memory.
2. Core Entities
| Entity | Responsibility | Key Attributes |
|---|---|---|
| Game | Orchestrates turns | players, board, currentPlayerIndex, status |
| Board | Layout and jumps | size, cellLinks |
| CellLink | Snake or ladder | fromIndex, toIndex, kind |
| Player | Token position | identifier, position |
| Dice | Produces next roll | interface roll |
| TurnResult | Outcome of one turn | steps, intermediate jumps |
3. Class Diagram
Loading diagram…
4. State / Sequence Diagram (where relevant)
Loading diagram…
5. Design Patterns Applied
- Strategy — Different win rules (exact end vs overshoot bounce). Strategy pattern.
- Template Method —
takeTurnskeleton with hooks for house rules. Template Method pattern.
6. Implementation
Go
package snakeladder
type Player struct {
Identifier string
Position int
}
type Board struct {
Size int
JumpTarget map[int]int
}
type Dice interface {
Roll() int
}
type Game struct {
Board Board
Players []Player
CurrentPlayer int
WinIndex int
Dice Dice
}
func (game *Game) TakeTurn() (TurnResult, error) { /* ... */ }JavaScript
class Board {
constructor({ size, jumps }) {
this.size = size;
this.jumpTarget = new Map(jumps);
}
resolveLanding(index) {
return this.jumpTarget.get(index) ?? index;
}
}
class Game {
constructor({ board, players, dice, exactFinish }) {
this.board = board;
this.players = players;
this.dice = dice;
this.exactFinish = exactFinish;
}
takeTurn() { /* ... */ }
}7. Concurrency / Thread Safety
- Collisions: Mostly single-threaded; online lobby could mutate game concurrently without locks if one goroutine owns match.
- Go: No shared state across matches;
Gamestays in one goroutine. - JavaScript: Event-loop single thread.
8. Extensibility & Followups
- Multiple dice, max moves per turn, power-ups on cells.
- Persistent leaderboards via repository adapter.
- Edge cases: infinite bounce when misconfigured links; validate DAG property for snakes/ladders.
Last updated on
Spotted something unclear or wrong on this page?