Skip to main content

Command Palette

Search for a command to run...

Snakes and Ladders (Low-Level Design)

Updated
4 min read
Snakes and Ladders (Low-Level Design)
S

As a software developer, I find immense joy in crafting elegant code and bringing ideas to life through programming. And when I'm not busy coding, you'll often find me creating content that showcases my passion for this fascinating world of software development.

Problem Definition

Snakes and Ladders is a popular board game enjoyed by people of all ages around the world. The game's objective is to move from the starting point to the finishing point, usually by rolling dice and moving the corresponding number of steps on the board. However, the presence of snakes and ladders on the board adds an element of luck and surprise to the game, making it more exciting to play.

Requirements

  1. Players will set the number of dice used at the start of the game.

  2. Each player will play turn by turn.

  3. More than 2 players should play the game.

  4. The game will end when there are only 2 players left.

  5. The player should reach exactly at last cell or should get a number in dice to reach beyond the last cell to win.

Objects

  1. Board

  2. Cell

  3. Snake

  4. Ladder

  5. Dice

  6. Game

  7. Player

UML Diagram

Code

See on GitHub

@Getter
public class Dice {
    private int diceCount;

    public Dice(int count)
    {
        diceCount= count;
    }

    public int rollDice()
    {
        int count=0, total=0;
        while(count< diceCount)
        {
            total+= ThreadLocalRandom.current().nextInt(1, 7);
            count++;
        }
        return total;
    }
}
@Getter
public class Snake {
    private int start;
    private int end;
    public Snake(int start, int end)
    {
        this.start= start;
        this.end= end;
    }
@Getter
public class Ladder {
    private int start;
    private int end;
    public Ladder(int start, int end)
    {
        this.start = start;
        this.end= end;
    }
}
@Getter
@Setter
public class Cell {
    private Snake snake;
    private Ladder ladder;

    public Cell(){
        snake= null;
        ladder= null;
    }

}
@Getter
public class Player {
    private int id;
    private String name;
    @Setter
    private int currentPosition;

    public Player(int id, String name){
        this.id= id;
        this.name= name;
        currentPosition= 1;
    }

}
@Getter
public class Board {
    private int boardSize;
    private int noOfSnake;
    private int noOfLadder;
    @Setter
    private Cell[][] cell= new Cell[1000][1000];

    public Board(int size, int snake, int ladder){
        boardSize= size;
        noOfSnake= snake;
        noOfLadder= ladder;

        initializeBoard();
    }

    private void initializeBoard()
    {
        for(int i=1; i<=boardSize; i++)
        {
            cell[generateRowNo(i)][generateColNo(i)]= new Cell();
        }
        generateSnakes();
        generateLadders();
    }
    private void generateSnakes()
    {
        int snakeCount=0;
        while(snakeCount< noOfSnake)
        {
            int start= ThreadLocalRandom.current().nextInt(2, boardSize);
            int end= ThreadLocalRandom.current().nextInt(2, boardSize);
            if(start<=end)
                continue;
            if(cell[generateRowNo(start)][generateColNo(start)].getSnake()==null)
            {
                cell[generateRowNo(start)][generateColNo(start)].setSnake(new Snake(start, end));
                snakeCount++;
            }

        }
    }
    private void generateLadders()
    {
        int ladderCount=0;
        while(ladderCount< getNoOfLadder())
        {
            int start= ThreadLocalRandom.current().nextInt(2, getBoardSize());
            int end= ThreadLocalRandom.current().nextInt(2, getBoardSize());
            if(start>=end)
                continue;
            if(cell[generateRowNo(start)][generateColNo(start)].getLadder()==null &&
                cell[generateRowNo(start)][generateColNo(start)].getSnake()==null)
            {
                cell[generateRowNo(start)][generateColNo(start)].setLadder(new Ladder(start, end));
                ladderCount++;
            }

        }
    }
    private int generateRowNo(int num)
    {
        int row= (int) (num-1/Math.sqrt(getBoardSize()));
        return row;
    }
    private int generateColNo(int num)
    {
        int col= (int) (num-1%Math.sqrt(getBoardSize()));
        return col;
    }
    public int getFinalPosition(int position)
    {
        int row= generateRowNo(position);
        int col= generateColNo(position);
        int finalPosition= position;
        if(cell[row][col].getSnake()!=null)
        {
            System.out.println("Snake bit at: " + position);
            finalPosition= cell[row][col].getSnake().getEnd();


        }
        else if (cell[row][col].getLadder()!=null)
        {
            System.out.println("Climbed ladder at: " + position);
            finalPosition= cell[row][col].getLadder().getEnd();

        }


        return finalPosition;
    }


}
@Getter
@Setter
public class Game {
    private Queue<Player> players= new ArrayDeque<Player>();
    private Board board;
    private Dice dice;

    public void addPlayers(int id, String name)
    {
        Player player= new Player(id, name);
        players.add(player);
        System.out.println("Player added: "+ name);
    }
    public void setBoard(int size, int snake, int ladder)
    {
        board= new Board(size, snake, ladder);
        System.out.println("Board set of size: "+ size);
        System.out.println("Snakes added:" + snake);
        System.out.println("Ladders added: "+ ladder);
    }
    public void setDice(int count)
    {
        dice= new Dice(count);
        System.out.println("No. of dice used: "+ count);
    }
    public void startGame()
    {
        List<String> winners= new ArrayList<>();
        while(players.size()>2)
        {
            Player player= players.poll();
            System.out.println("Turn: " + player.getName());
            System.out.println(player.getName() + " is at : " + player.getCurrentPosition());
            int move= dice.rollDice();
            System.out.println("Dice shows : " + move);
            int currentPosition= player.getCurrentPosition() + move;
            if(currentPosition>=board.getBoardSize())
            {
                winners.add(player.getName());
                System.out.println(player.getName() + " won");
                continue;
            }
            if(currentPosition< board.getBoardSize())
            {
                int finalPosition = board.getFinalPosition(currentPosition);
                player.setCurrentPosition(finalPosition);
                System.out.println(player.getName() + " moved to : " + finalPosition);
            }
            players.add(player);

        }
        System.out.println("Game Over");
        displayResult(winners);
    }
    private void displayResult(List<String> winners)
    {
        System.out.println("Results:");
        int count=0;
        for(String playerName: winners)
        {
            count++;
            System.out.println("Rank " + count + ": " + playerName);

        }
    }
}
public class SnakeLadderApplication {
    public static void main(String args[])
    {
        Game game= new Game();
        game.setDice(2);
        game.setBoard(100, 4, 3);
        game.addPlayers(1, "Swati");
        game.addPlayers(2, "Shristi");
        game.addPlayers(3, "Shivani");
        game.addPlayers(4, "Sonal");
        game.startGame();
    }
}

In this blog post, we have explored the technical aspects of implementing Snake and Ladder, including board layout, movement rules, and gameplay mechanics. We have discussed how to represent the game state using data structures, and examined the algorithms for handling player movement, snake bites, and ladder climbs.

T

I have been following your LLD blog and I must say it is very informative, detailed and with detailed explanation. Please keep up the good work! Just one question - how/where do you generative these UML diagrams?

A

Very informative and well written 👏

1
A

Thanks

1

Low Level Design Problems

Part 3 of 4

I will discuss popular low-level design problems frequently asked in interviews. I will post code samples (in Java) and UML Class diagrams for each problem which will help you visualize the solution.

Up next

Parking Lot (Low-Level Design)

Problem definition A parking lot is a designated area for parking vehicles and is a feature found in almost all popular venues such as shopping malls, sports stadiums, offices, etc. In a parking lot, there are different parking spots available for di...