module Roller.Core (main) where import Roller.Types import Roller.Parse import Roller.CLI import System.Environment (getArgs) import System.Random (randomRIO) import Control.Applicative hiding (Const) import Control.Monad (join, replicateM, replicateM_) rolls :: Int -> Int -> IO [Int] rolls n s = replicateM n . randomRIO $ (1,s) roll :: DiceExp -> IO [[Int]] roll de = case de of Sum e1 e2 -> (++) <$> roll e1 <*> roll e2 Const n -> return [[n]] Die n s -> return <$> n `rolls` s rollEm :: CLI (IO ()) rollEm verbose n args = maybe parseFail rollMany (parse input) where input = concat args rollMany = replicateM_ n . rollOnce rollOnce exp = fmap summary (roll exp) >>= putStrLn summary = if verbose then show else show . sumRolls sumRolls = sum . map sum parseFail = putStrLn $ "Could not parse \"" ++ input ++ "\" as dice expression!" main :: IO () main = join . withOpts $ rollEm