## Programming Praxis – Chutes And Ladders

In today’s Programming Praxis exercise, our goal is to simulate the board game Chutes and Ladders. Let’s get started, shall we?

Some imports:

```import Control.Monad
import System.Random
```

First, we write a function to handle the chutes and ladders. If a player lands on one these squares, he automatically moves to the corresponding destination.

```promote :: Num a => a -> a
promote n = maybe n id \$ lookup n [(16,6), (47,26), (49,11), (56,53),
(62,19), (64,60), (87,24), (93,73), (95,75), (98,78), (1,38), (4,14),
(9,31), (21,42), (28,84), (36,44), (51,67), (71,91), (80,100)]
```

A single player game consists of throwing dice until you land on the goal.

```game :: IO [Int]
game = fmap (tail . turn 0 . randomRs (1,6)) newStdGen where
turn 100 _       = 
turn n   ~(d:ds) = n : turn (if n+d > 100 then n else promote \$ n+d) ds
```

The length of a multiplayer game can be determined by taking the shortest of k single player games. For the statistics, we look at the shortest game, the longest game and the average length.

```stats :: Int -> Int -> IO (Int, Int, Float)
stats k n = fmap (\rs -> (minimum rs, maximum rs, average rs)) .
replicateM n . fmap minimum . replicateM k \$ fmap length game where
average xs = fromIntegral (sum xs) / fromIntegral n
```

We simulate the results for games with one to five players.

```main :: IO ()
main = do print =<< stats 1 100000
print =<< stats 2 100000
print =<< stats 3 100000
print =<< stats 4 100000
print =<< stats 5 100000
```

One run produced the following results:

```(7,232,39.391)
(7,127,26.2546)
(7,91,21.8529)
(7,73,19.3968)
(7,57,17.7395)```

The results are within tolerance of the ones produced by the Scheme version. As a regular player of board games myself, I must say this seems like a fairly rubbish game. There’s no interaction, no strategy, the winner is determined purely by chance and the game can theoretically last infinitely long. Do yourself a favor and go play a good game instead.