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