Snake and Ladder Game
Problem Statement
Section titled “Problem Statement”Design a Snake and Ladder board game that can be played by multiple players. The system should handle game initialization, player movements, snake and ladder mechanics, dice rolls, turn management, and determine the winner. Support both human and computer players.
Requirements
Section titled “Requirements”Functional Requirements
Section titled “Functional Requirements”- Initialize game board with configurable size (default 100 cells)
- Place snakes and ladders at specific positions
- Support 2-4 players
- Roll dice (1-6) for each player’s turn
- Move player tokens based on dice roll
- Handle snake bites (move down)
- Handle ladder climbs (move up)
- Determine winner when a player reaches the final cell
- Handle exact landing on final cell
- Support both human and AI players
Non-Functional Requirements
Section titled “Non-Functional Requirements”- Fair random dice generation
- Clear game state visualization
- Turn-based sequential gameplay
- Extensible for different board sizes
- Support game state persistence
Simplified Class Diagram
Section titled “Simplified Class Diagram”Simplified Overview
Section titled “Simplified Overview”Detailed Class Diagram
Section titled “Detailed Class Diagram”Key Design Patterns
Section titled “Key Design Patterns”- Factory Pattern: Create different player types
- Strategy Pattern: Different display strategies
- Observer Pattern: Game state notifications
- Builder Pattern: Game configuration
- Singleton Pattern: Game controller
Design Pattern Diagrams
Section titled “Design Pattern Diagrams”1. Builder Pattern - Game Configuration
Section titled “1. Builder Pattern - Game Configuration”2. Strategy Pattern - Player Behavior
Section titled “2. Strategy Pattern - Player Behavior”3. Observer Pattern - Game Events
Section titled “3. Observer Pattern - Game Events”Code Snippets
Section titled “Code Snippets”Initialize Game Board
Section titled “Initialize Game Board”public class Board { private int size; private Map<Integer, Snake> snakes; private Map<Integer, Ladder> ladders;
public Board(int size) { this.size = size; this.snakes = new HashMap<>(); this.ladders = new HashMap<>(); initializeDefaultSnakesAndLadders(); }
private void initializeDefaultSnakesAndLadders() { // Add snakes (head -> tail) addSnake(new Snake(99, 54)); addSnake(new Snake(70, 55)); addSnake(new Snake(52, 42)); addSnake(new Snake(25, 2)); addSnake(new Snake(95, 72));
// Add ladders (start -> end) addLadder(new Ladder(6, 25)); addLadder(new Ladder(11, 40)); addLadder(new Ladder(60, 85)); addLadder(new Ladder(46, 90)); addLadder(new Ladder(17, 69)); }
public void addSnake(Snake snake) { if (snake.getHead() <= snake.getTail()) { throw new IllegalArgumentException("Snake head must be greater than tail"); } snakes.put(snake.getHead(), snake); }
public void addLadder(Ladder ladder) { if (ladder.getStart() >= ladder.getEnd()) { throw new IllegalArgumentException("Ladder start must be less than end"); } ladders.put(ladder.getStart(), ladder); }
public int getNewPosition(int position) { // Check for snake if (snakes.containsKey(position)) { return snakes.get(position).getTail(); }
// Check for ladder if (ladders.containsKey(position)) { return ladders.get(position).getEnd(); }
return position; }}Play Turn
Section titled “Play Turn”public class Game { public void playTurn() { if (isGameOver) { return; }
Player currentPlayer = getCurrentPlayer();
// Roll dice int diceRoll = dice.roll(); display.showDiceRoll(currentPlayer, diceRoll);
// Calculate new position int currentPosition = currentPlayer.getCurrentPosition(); int newPosition = currentPosition + diceRoll;
// Check if exceeds board if (newPosition > board.getSize()) { display.showMove(currentPlayer, currentPosition, currentPosition); nextTurn(); return; }
// Move player movePlayer(currentPlayer, newPosition);
// Check for winner if (checkWinner(currentPlayer)) { winner = currentPlayer; isGameOver = true; display.showWinner(winner); return; }
// Next player's turn nextTurn(); }
private void movePlayer(Player player, int newPosition) { int currentPosition = player.getCurrentPosition();
// Move to new position player.setCurrentPosition(newPosition); display.showMove(player, currentPosition, newPosition);
// Check for snake or ladder int finalPosition = board.getNewPosition(newPosition);
if (finalPosition != newPosition) { if (finalPosition < newPosition) { // Snake bite display.showSnakeBite(player, newPosition, finalPosition); } else { // Ladder climb display.showLadderClimb(player, newPosition, finalPosition); } player.setCurrentPosition(finalPosition); }
// Record move history.addMove(new Move(player, dice.getLastRoll(), currentPosition, player.getCurrentPosition())); }
private void nextTurn() { currentPlayerIndex = (currentPlayerIndex + 1) % players.size(); }
private boolean checkWinner(Player player) { return player.getCurrentPosition() == board.getSize(); }}Dice Roll
Section titled “Dice Roll”public class Dice { private int numberOfDice; private int minValue; private int maxValue; private Random random; private int lastRoll;
public Dice() { this(1); // Single dice by default }
public Dice(int numberOfDice) { this.numberOfDice = numberOfDice; this.minValue = 1; this.maxValue = 6; this.random = new Random(); }
public int roll() { int sum = 0; for (int i = 0; i < numberOfDice; i++) { sum += generateRandom(); } lastRoll = sum; return sum; }
private int generateRandom() { return random.nextInt(maxValue - minValue + 1) + minValue; }
public int getLastRoll() { return lastRoll; }}Game Controller
Section titled “Game Controller”public class GameController { private Game game; private Display display; private Scanner scanner;
public void initializeGame(int boardSize, int playerCount) { game = new Game(boardSize); display = new ConsoleDisplay(); scanner = new Scanner(System.in);
// Add players for (int i = 0; i < playerCount; i++) { System.out.println("Enter name for Player " + (i + 1) + ":"); String name = scanner.nextLine();
System.out.println("Player type? (1: Human, 2: Computer):"); int type = scanner.nextInt(); scanner.nextLine(); // Consume newline
Player player; if (type == 1) { player = new HumanPlayer("P" + (i + 1), name); } else { player = new ComputerPlayer("P" + (i + 1), name); }
game.addPlayer(player); } }
public void startGame() { display.showBoard(game.getBoard(), game.getPlayers());
while (!game.isGameOver()) { Player currentPlayer = game.getCurrentPlayer(); display.showPlayerTurn(currentPlayer);
if (currentPlayer instanceof HumanPlayer) { System.out.println("Press Enter to roll dice..."); scanner.nextLine(); } else { // Small delay for computer player try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }
game.playTurn(); showGameStatus(); }
System.out.println("\nGame Over!"); display.showWinner(game.getWinner()); }
private void showGameStatus() { System.out.println("\n--- Current Positions ---"); for (Player player : game.getPlayers()) { System.out.println(player.getName() + ": " + player.getCurrentPosition()); } System.out.println("------------------------\n"); }}Console Display
Section titled “Console Display”public class ConsoleDisplay implements Display { @Override public void showDiceRoll(Player player, int roll) { System.out.println(player.getName() + " rolled a " + roll); }
@Override public void showMove(Player player, int from, int to) { if (from == to) { System.out.println(player.getName() + " cannot move (would exceed board)"); } else { System.out.println(player.getName() + " moved from " + from + " to " + to); } }
@Override public void showSnakeBite(Player player, int from, int to) { System.out.println("🐍 Oh no! " + player.getName() + " was bitten by a snake at " + from + " and slid down to " + to); }
@Override public void showLadderClimb(Player player, int from, int to) { System.out.println("🪜 Great! " + player.getName() + " found a ladder at " + from + " and climbed up to " + to); }
@Override public void showWinner(Player player) { System.out.println("\n🎉 Congratulations! " + player.getName() + " has won the game! 🎉"); }
@Override public void showPlayerTurn(Player player) { System.out.println("\n>>> " + player.getName() + "'s turn <<<"); }
@Override public void showBoard(Board board, List<Player> players) { System.out.println("=== Snake and Ladder Game ==="); System.out.println("Board Size: " + board.getSize()); System.out.println("Players: " + players.size()); System.out.println("=============================\n"); }}Main Game Entry
Section titled “Main Game Entry”public class SnakeAndLadderGame { public static void main(String[] args) { GameController controller = new GameController();
System.out.println("Welcome to Snake and Ladder Game!"); System.out.println("================================\n");
Scanner scanner = new Scanner(System.in);
System.out.print("Enter board size (default 100): "); int boardSize = scanner.nextInt();
System.out.print("Enter number of players (2-4): "); int playerCount = scanner.nextInt(); scanner.nextLine(); // Consume newline
if (playerCount < 2 || playerCount > 4) { System.out.println("Invalid number of players. Setting to 2."); playerCount = 2; }
controller.initializeGame(boardSize, playerCount); controller.startGame();
scanner.close(); }}Extension Points
Section titled “Extension Points”- Add power-ups and special cells
- Implement multiplayer over network
- Add different game modes (timed, race)
- Support custom board configurations
- Add player statistics and leaderboards
- Implement undo/redo functionality
- Add sound effects and animations
- Support different dice types (4-sided, 8-sided)
- Add tournament mode with multiple rounds
- Implement save/load game state