-- -- | This module is for throwing dice for e.g. RPGs. (\@dice 3d6+2) -- -- Copyright Einar Karttunen 2005-04-06. -- module Plugin.Dice (theModule) where import Plugin import Control.Monad (replicateM,foldM) import System.Random (randomRIO) import Text.ParserCombinators.Parsec PLUGIN Dice instance Module DiceModule () where moduleCmds _ = ["dice"] moduleHelp _ _ = "dice . Throw random dice. is of the form 3d6+2." process_ _ _ xs = ios (dice xs) dice :: String -> IO String dice str = case parse expr "dice" (filter (not.isSpace) str) of Left err -> return $ show err Right e -> do res <- eval e return (str++" => "++show res) eval :: [(Int, Int)] -> IO Int eval = foldM ef 0 where ef acc (v,1) = return (acc+v) ef acc (n,d) = if n > 100 then return 0 else do ls <- replicateM n (randomRIO (1,d)) return (acc + sum ls) expr :: CharParser st [(Int, Int)] expr = primExp `sepBy1` (char '+') primExp :: CharParser st (Int, Int) primExp = do v <- number d <- option 1 (char 'd' >> number) return (v,d) number :: CharParser st Int number = read `fmap` many1 digit