all repos — paprika @ seen-cmd

go rewrite of taigabot

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}