Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Simple Snake and Ladders gameplay implementation in Haskell
{-# LANGUAGE RecordWildCards #-}
module Main where
import qualified Data.Map as Map
import Control.Monad.State
import System.Random
import Data.Maybe
import Debug.Trace
main :: IO ()
main = do
g <- newStdGen
let board = Board 10 $ Map.fromList [(3, 7), (8, 4)]
let players = Map.fromList [ (0, Player 0 0)
, (1, Player 1 0)
, (2, Player 2 0)]
let winner = evalState (playGame board players) g
putStrLn $ "Winner is " ++ show winner
data Player = Player { playerId :: Int, playerPos :: Int }
deriving (Show, Eq)
data Board = Board { boardSize :: Int, boardJumps :: Map.Map Int Int}
deriving (Show, Eq)
rollDice :: State StdGen Int
rollDice = do
g <- get
let (r, g') = randomR (1, 6) g
put g'
return r
move :: Board -> Player -> State StdGen Player
move Board {..} player@Player {..} = traceShow player $ do
roll <- rollDice
let nextPos = trace ("Player " ++ show playerId ++ " rolled " ++ show roll) $
playerPos + roll
if nextPos >= boardSize
then return player
else case Map.lookup nextPos boardJumps of
Nothing -> return $ Player playerId nextPos
Just jumpPos -> return $ Player playerId jumpPos
playGame :: Board -> Map.Map Int Player -> State StdGen Player
playGame board@Board {..} initPlayers = go 0 initPlayers
where
go playerId players = do
let player = fromJust $ Map.lookup playerId players
player' <- move board player
if isWinner player'
then return player'
else do
let nextId = (playerId + 1) `mod` Map.size players
go nextId (Map.insert playerId player' players)
isWinner Player {..} = playerPos == boardSize - 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment