plugins/decide.go (view raw)
1package plugins
2
3import (
4 "fmt"
5 "math/rand"
6 "strconv"
7 "strings"
8
9 "gopkg.in/irc.v3"
10)
11
12type Decide struct{}
13
14func init() {
15 Register(Decide{})
16}
17
18func (Decide) Triggers() []string {
19 return []string{".decide", ".dice", ".roll"}
20}
21
22func (Decide) Execute(m *irc.Message) (string, error) {
23 params := strings.Split(m.Trailing(), " ")
24
25 trigger := params[0]
26 if trigger == ".decide" {
27 var terms []string
28 var currTerm strings.Builder
29 for _, word := range params[1:] {
30 if word == "" {
31 continue
32 }
33
34 if word == "or" && currTerm.Len() != 0 {
35 terms = append(terms, currTerm.String())
36 currTerm.Reset()
37 } else {
38 currTerm.WriteString(word)
39 currTerm.WriteByte(' ')
40 }
41 }
42 if currTerm.Len() > 0 {
43 terms = append(terms, currTerm.String())
44 }
45
46 if len(terms) < 1 {
47 return "Usage: .decide proposition 1 [ or proposition 2 [ or proposition n ... ] ]", nil
48 } else if len(terms) < 2 {
49 return []string{"Yes.", "No."}[rand.Intn(2)], nil
50 } else {
51 return terms[rand.Intn(len(terms))], nil
52 }
53 } else if trigger == ".dice" || trigger == ".roll" {
54 if len(params) != 2 {
55 return "usage: .dice NNdXX - where NN is 1-36 and XX is 2-64", nil
56 }
57 dice := params[1]
58 if len(dice) > 5 {
59 return "Invalid dice specification: too big", nil
60 }
61
62 spec := strings.SplitN(dice, "d", 2)
63 if len(spec) != 2 {
64 return "Invalid dice specification: no separating 'd'", nil
65 }
66
67 numDie, err := strconv.Atoi(spec[0])
68 if err != nil || numDie < 1 || numDie > 36 {
69 return fmt.Sprintf("Invalid dice count: %s is not a number or is not between 1-36", spec[0]), nil
70 }
71 numDieFaces, err := strconv.Atoi(spec[1])
72 if err != nil || numDieFaces < 2 || numDieFaces > 64 {
73 return fmt.Sprintf("Invalid dice face count: %s is not a number or is not between 2-64", spec[0]), nil
74 }
75
76 var result strings.Builder
77 sum := 0
78 for i := 0; i < numDie; i++ {
79 r := rand.Intn(numDieFaces) + 1
80 sum += r
81 result.WriteString(strconv.Itoa(r))
82 result.WriteByte(' ')
83 }
84 result.WriteByte('=')
85 result.WriteByte(' ')
86 result.WriteString(strconv.Itoa(sum))
87 return result.String(), nil
88 }
89
90 panic("Unreachable!")
91}