## DEV Community is a community of 879,630 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

dev.to staff

Posted on

# Daily Challenge #207 - Snakes and Ladders

Implement a function called `SnakesLadders` to play a two-player game of Snakes and Ladders. The function should keep track of player turns and player position on the board (of the 100 spaces). SnakesLadders should call a method `play(die1, die2)` independently of the state of the game or the player turn. These variables are the die thrown in a turn and are both integers between 1 and 6. The player moves the sum of die1 and die 2.

Rules

1. There are two players and both start off the board on square 0.
2. Player 1 starts and alternates with player 2.
3. You follow the numbers up the board in order 1=>100
4. If the value of both die are the same then that player will have another go.
5. Climb up ladders. The ladders on the game board allow you to move upwards and get ahead faster. If you land exactly on a square that shows an image of the bottom of a ladder, then you may move the player all the way up to the square at the top of the ladder. (even if you roll a double).
6. Slide down snakes. Snakes move you back on the board because you have to slide down them. If you land exactly at the top of a snake, slide move the player all the way to the square at the bottom of the snake or chute. (even if you roll a double).
7. Land exactly on the last square to win. The first person to reach the highest square on the board wins. But there's a twist! If you roll too high, your player "bounces" off the last square and moves back. You can only win by rolling the exact number needed to land on the last square. For example, if you are on square 98 and roll a five, move your game piece to 100 (two moves), then "bounce" back to 99, 98, 97 (three, four then five moves.)

Return `Player n Wins!`. Where n is winning player that has landed on square 100 without any remaining moves left.

Return `Game over!` if a player has won and another player tries to play.

Otherwise return `Player n is on square x.` Where n is the current player and x is the square they are currently on.

Good luck!

This challenge comes from adrian.eyre on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

## Discussion (5)

Avalander • Edited on

## Scala

Instead of saving the state internally, the `play` function receives a state object and returns a new state object to keep it pure.

``````object LaddersAndSnakes {
2 -> 38,
7 -> 14,
8 -> 31,
15 -> 26,
16 -> 6,
21 -> 42,
28 -> 84,
36 -> 44,
46 -> 25,
49 -> 11,
51 -> 67,
62 -> 19,
64 -> 60,
71 -> 91,
74 -> 53,
78 -> 98,
87 -> 94,
92 -> 88,
95 -> 75,
99 -> 80,
)

sealed trait Player
case object Player1 extends Player
case object Player2 extends Player

sealed trait State
case class Playing(p1: Int, p2: Int, next: Player) extends State {
val nextPos = next match {
case Player1 => p1
case Player2 => p2
}
}
case class Win(p: Player) extends State
case object GameOver extends State

object State {
def start (): State = Playing(1, 1, Player1)
}

type Roll = (Int, Int)

def play (s: State, r: Roll): State = s match {
case GameOver           => GameOver
case Win(_)             => GameOver
case Playing(p1, p2, n) => nextTurn(Playing(p1, p2, n), r)
}

private def nextTurn (s: Playing, roll: Roll): State = {
val Playing(p1, p2, next) = s
val player = s.nextPos
val nextPos = updatePosition(player, roll)

if (nextPos == 100) Win(next)
else if (isDouble(roll)) next match {
case Player1 => Playing(nextPos, p2, Player1)
case Player2 => Playing(p1, nextPos, Player2)
}
else next match {
case Player1 => Playing(nextPos, p2, Player2)
case Player2 => Playing(p1, nextPos, Player1)
}
}

private def updatePosition (pos: Int, roll: Roll): Int = {
val (d1, d2) = roll
val nextPos = clamp(pos + d1 + d2, 100)

case None    => nextPos
case Some(v) => v
}
}

private def clamp (v: Int, limit: Int): Int = {
if (v <= limit) v
else limit - (v - limit)
}

private def isDouble (r: Roll): Boolean = {
r._1 == r._2
}
}
``````
DynamicBoy24

which language is this

Vidit Sarkar

It was fun

``````#include <bits/stdc++.h>
using namespace std;

// returns the sum of numbers in die1 and die2 and also whether they are same or not
// Example : die1 = 4, die2 = 5  => return <9, false>
// Example : die1 = 3, die2 = 3  => return <6, true>
pair<int, bool> play(){
int die1 = rand()%6 + 1;
int die2 = rand()%6 + 1;

return make_pair(die1 + die2, die1==die2);
}

// main snake and ladder game
srand(time(0));

// differnt positions of snake and ladders
// first one is starting position and second one is ending position
{99,80},
{95,75},
{92,88},
{89,68},
{74,53},
{64,60},
{62,19},
{49,11},
{46,25},
{16,6},
{2,38},
{7,14},
{8,31},
{15,26},
{21,42},
{28,84},
{36,44},
{51,67},
{71,91},
{78,98},
{87,94}
};

int playerPos[2] = {0,0}; // positions of player1 and player2 respectively
int turn = 0; // 0 if it is player1's turn, 1 if player2's turn

while(true){
pair<int, bool> move = play(); // roll the dies
playerPos[turn] += move.first; // make the move

// prints the move
cout << "Player " << turn+1 << "'s turn : " << move.first;
if(move.second)
cout << " and double chance";
cout << "\n";

// bounce off if move takes player to position greater than 100
if(playerPos[turn] > 100){
cout << "Player " << turn+1 << " bounces off from " << playerPos[turn] << " to ";
playerPos[turn] = 200 - playerPos[turn];
cout << playerPos[turn] << ".\n";
}

// if snake or ladder then go the position indicated
cout << "Player " << turn+1 << " is snaked from " << playerPos[turn] << " to ";
else
cout << "Player " << turn+1 << " is laddered from " << playerPos[turn] << " to ";
cout  << playerPos[turn] << "\n";
}

// this part handles the case if the player reaches the goal or not
// if goal is reached then prints the winner and break the loop
if(playerPos[turn] == 100){
cout << "Player " << turn+1 << " wins!\nGame over for Player " << 2-turn << ".\n";
break;
}

// if player does not have a second move
// then its turn for other player
if(!move.second)
turn = 1 - turn;
cout << "Player 1 is on square "<< playerPos[0] << ".\n";
cout << "Player 2 is on square "<< playerPos[1] << ".\n\n";
this_thread::sleep_for(chrono::milliseconds(500)); // prints after 0.5sec gap
}
}

// main function
int main(){