Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update roll command, added joinNumbers #58

Merged
merged 15 commits into from
Nov 12, 2023
61 changes: 35 additions & 26 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,46 +526,55 @@ func (b *bot) ban(m dggchat.Message, s *dggchat.Session) {
}
}

// !roll sides [count] - roll dice
func (b *bot) roll(m dggchat.Message, s *dggchat.Session) {
if !strings.HasPrefix(m.Message, "!roll") {
return
}
func compute(input string) (int, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we call this computeRoll or something more descriptive?


parts := strings.Split(m.Message, " ")
if len(parts) < 2 {
return
// Define a regular expression to extract dice rolling information
regexPattern := `^!roll\s+(\d+)d(\d+)\s*([+\-]\s*\d+)?(.*?)$`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also support rolls with an s

regex := regexp.MustCompile(regexPattern)

// Match the regular expression against the input string
matches := regex.FindStringSubmatch(input)

if matches == nil {
return 0, fmt.Errorf("Invalid input format: %s", input)
}

args := parts[1:]
// Extract matched values
numDice, _ := strconv.Atoi(matches[1])
numSides, _ := strconv.Atoi(matches[2])
modifierStr := matches[3]

// parse XdY
if strings.Contains(parts[1], "d") {
parts := strings.Split(parts[1], "d")
args = []string{parts[1], parts[0]}
if math.MaxInt64/numDice <= numSides || numDice > 100 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

math.MaxInt64/numDice <= numSides is meant to check whether or not this could cause integer overflow. we also need to factor in the modifier now

return 0, fmt.Errorf("Sides or count too large")
}

sides, _ := strconv.ParseUint(args[0], 10, 64)
if sides < 2 {
return
// Roll the dice
result := 0
for i := 0; i < numDice; i++ {
result += rand.Intn(numSides) + 1
}

count := uint64(1)
if len(args) > 1 {
c, _ := strconv.ParseUint(args[1], 10, 64)
if c != 0 {
count = c
}
// Apply the modifier if present
if modifierStr != "" {
modifier, _ := strconv.Atoi(modifierStr)
result += modifier
}

if math.MaxInt64/count <= sides || count > 100 {
return result, nil
}

// !roll sides [count] - roll dice
func (b *bot) roll(m dggchat.Message, s *dggchat.Session) {
if !strings.HasPrefix(m.Message, "!roll") {
return
}

var sum int64
for i := uint64(0); i < count; i++ {
sum += rand.Int63n(int64(sides)) + 1
parts := strings.Split(m.Message, " ")
if len(parts) < 2 {
return
}

var sum, _ = compute(m.Message)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: sum, _ := ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: need to check error here and return without responding to invalid input


b.sendMessageDedupe(fmt.Sprintf("%s rolled %d", m.Sender.Nick, sum), s)
}
27 changes: 27 additions & 0 deletions commands_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"testing"
)

Expand All @@ -20,3 +21,29 @@ func TestParseModifiers(t *testing.T) {
}
// fmt.Println(err.Error())
}

func TestCompute(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

testInputs := [11]string{
"!roll 2d2+100 foo biz baz",
"!roll 2d2 + 100",
"!roll 2d2 +100",
"!roll 2d2+ 100",
"!roll 2d2-100",
"!roll 2d2 - 100",
"!roll 2d2 -100",
"!roll 2d2- 100",
"!roll 2d2- 100 foo biz baz",
"!roll 23904823904823904823490d20 +1",
"!roll 2d20"}

for _, input := range testInputs {
result, err := compute(input)
errorMessage := fmt.Sprintf("%v", err)
if err != nil {
if errorMessage != "Sides or count too large" {
t.Error(fmt.Sprintf("Error: %v\n %d", err, result))
}
}
}

}