-
Notifications
You must be signed in to change notification settings - Fork 0
/
DicePlugin.hs
83 lines (70 loc) · 3.15 KB
/
DicePlugin.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module DicePlugin
( plugin
) where
-- This plugin very needs refactorization in terms of evaluate-try-exceptions, it stinks
import Control.Monad(when)
import Control.Monad.Random(evalRandIO, getRandomR, RandomGen, Rand)
import Control.Exception(try, evaluate, SomeException)
import qualified Data.Text as T(Text, isPrefixOf, pack)
import IrcUtilities(IrcMsg(Privmsg), Bot(Bot), Plugin(Plugin), privmsgTo, bNick, readInt)
import Redirection(unwrapRedirectFromMsg)
-- Plugin Info
plugin :: Plugin
plugin = Plugin "DicePlugin" run helpAvailableUserCmds helpAvailableModCmds helpCmd
-- Main run
run :: IrcMsg -> Bot -> IO [T.Text]
run (Privmsg author channel message) bot@(Bot _ config _) = when (",dice" `T.isPrefixOf` message') $ do
response <- parse message'
msgTo channel target response
where
(message', target) = unwrapRedirectFromMsg message author (bNick config)
run _ _ = return []
parse :: T.Text -> IO T.Text
parse msg
| argsCount == 1 = parse0
| argsCount == 2 = parse1 (args !! 1)
| argsCount == 3 = parse2 (args !! 1) (args !! 2)
| otherwise = return "Nieprawidlowa liczba argumentow dla ,dice"
where
args = words msg
argsCount = length args
-- It can be refactorized to one-liner
parse0 :: IO T.Text
parse0 = do
value <- evalRandIO (dice 1 6)
return $ (append "Wylosowana liczba (1-6) to " . T.pack . show) value
-- Code below, parse1 and parse2 needs refactorization
parse1 :: T.Text -> IO T.Text
parse1 arg1 = do
max' <- (try . evaluate . readInt) arg1 :: IO (Either SomeException Int)
case max' of
Right max -> if max >= 1 then do
value <- evalRandIO (dice 1 max)
return ("Wylosowana liczba (1-" ++ show max ++ ") to " ++ show value)
else
return "Musisz podac liczbe wieksza od zera"
Left e -> return "Jeden z argumentow nie jest liczba"
parse2 :: String -> String -> IO String
parse2 arg1 arg2 = do
min' <- (try . evaluate . readInt) arg1 :: IO (Either SomeException Int)
max' <- (try . evaluate . readInt) arg2 :: IO (Either SomeException Int)
case (min', max') of
(Right min, Right max) -> if min <= max then do
value <- evalRandIO (dice min max)
return ("Wylosowana liczba (" ++ show min ++ "-" ++ show max ++ ") to " ++ show value)
else
return "Musisz podac liczbe wieksza od zera"
(_, _) -> return "Jeden z argumentow nie jest liczba"
dice :: (RandomGen g) => Int -> Int -> Rand g Int
dice x y = getRandomR (x,y)
-- Help
helpAvailableUserCmds :: [String]
helpAvailableUserCmds = ["dice"]
helpAvailableModCmds :: [String]
helpAvailableModCmds = []
helpCmd :: String -> [String]
helpCmd "dice" = [
",dice # Wyświetla losową liczbę pomiędzy 1 i 6",
",dice <n> # Wyświetla losową liczbę pomiędzy 1 i <n>",
",dice <min> <max> # Wyświetla losową liczbę pomiędzy <min> i <max>"
]