packages feed

hid-examples-0.2: weapons.hs

import Data.List (group, sort)
import Control.Monad (replicateM)
import Control.Monad.State
import System.Random

data Weapon = Rock | Paper | Scissors
  deriving (Show, Bounded, Enum, Eq, Ord)

data Winner = First | Second | Draw
  deriving (Show, Eq, Ord)

winner :: (Weapon, Weapon) -> Winner
winner (Paper, Rock) = First
winner (Scissors, Paper) = First
winner (Rock, Scissors) = First
winner (w1, w2) = if w1 == w2 then Draw else Second

instance Random Weapon where
    randomR (a,b) g = case randomR (fromEnum a, fromEnum b) g of
                        (r, g') -> (toEnum r, g')
    random g = randomR (minBound, maxBound) g


randomWeapon :: State StdGen Weapon
randomWeapon = state random

gameRound :: State StdGen (Weapon, Weapon)
gameRound = (,) <$> randomWeapon <*> randomWeapon

game :: Int -> State StdGen [(Winner, Int)]
game n = counts <$> replicateM n (winner <$> gameRound)
  where
    counts xs = map (\xs@(x:_) -> (x, length xs)) $ group $ sort xs
    
main = do
  g <- newStdGen
  let r = evalState (game 10) g
  print r