From 0c89d7ea73744505e79e5e8f0f38ba47847600cb Mon Sep 17 00:00:00 2001 From: Brad Dunn Date: Wed, 13 Nov 2024 07:41:33 -0500 Subject: [PATCH] feat: negative modifiers Fixes #1 --- cmd/roll.go | 16 ++++++++++++++-- cmd/roll_test.go | 13 +++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/cmd/roll.go b/cmd/roll.go index ded5542..2e65f85 100644 --- a/cmd/roll.go +++ b/cmd/roll.go @@ -25,6 +25,7 @@ import ( "fmt" "math" "math/rand" + "regexp" "strconv" "strings" "time" @@ -93,7 +94,7 @@ func parseDie(die string) (Die, error) { } sides, err := strconv.Atoi(parts[1]) if err != nil { - return d, fmt.Errorf("invalid die sides: %s", parts[1]) + return d, fmt.Errorf("invalid die sides: %s, error: %v", parts[1], err) } d.Count = count d.Sides = sides @@ -103,7 +104,18 @@ func parseDie(die string) (Die, error) { func parseExpression(expression string) ([]Die, error) { var dice []Die var modifier int - for _, die := range strings.Split(expression, "+") { + + // Define a regular expression to capture parts of the dice rolls and modifiers + regex := `([+-]?\d*d\d+|[+-]?\d+)` + re := regexp.MustCompile(regex) + + // Extract all matches from the string + matches := re.FindAllString(expression, -1) + + for _, die := range matches { + die = strings.TrimSpace(die) + + // Die expression if strings.Contains(die, "d") { d, err := parseDie(die) if err != nil { diff --git a/cmd/roll_test.go b/cmd/roll_test.go index 72fcd88..473ccdc 100644 --- a/cmd/roll_test.go +++ b/cmd/roll_test.go @@ -103,3 +103,16 @@ func TestAddingModifiers(t *testing.T) { t.Errorf("RollDice(%s) = %d; want %d", input, result.Total, expected) } } + +func TestNegativeModifier(t *testing.T) { + r := &mockRand{value: 3} + input := "1d6-2" + expected := 2 + result, err := RollDice(r, input) + if err != nil { + t.Errorf("RollDice(%s) = %d; want %d", input, result.Total, expected) + } + if result.Total != expected { + t.Errorf("RollDice(%s) = %d; want %d", input, result.Total, expected) + } +}