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