Created
September 12, 2015 11:37
-
-
Save abhin4v/e17efaaf957291337c31 to your computer and use it in GitHub Desktop.
Simple Snake and Ladders gameplay implementation in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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