summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2017-01-26 02:24:39 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2017-01-26 02:24:39 -0500
commit76cecfa4d41e1c8d32e2be194b2ccd1007a820b4 (patch)
treedb4bf6551a13d097293bcfe754c8d7e136339236
parentc991679f760fc792fc74dafbd4fbcdc826c44c04 (diff)
roll: Support more complex rolls.
-rw-r--r--roll.go87
1 files changed, 63 insertions, 24 deletions
diff --git a/roll.go b/roll.go
index 414b0d2..5a02138 100644
--- a/roll.go
+++ b/roll.go
@@ -8,10 +8,13 @@ import (
"os"
"regexp"
"strconv"
+ "strings"
)
func usage() {
- fmt.Printf("Arguments are in the format [<COUNT>]d<SIZE>[+<MOD>]\n")
+ fmt.Printf("Usage: %s <SPECSLIST>...\n", os.Args[0])
+ fmt.Println("SPECLIST = [-]SPEC[<<+|->SPEC>...]")
+ fmt.Println("SPEC = [<COUNT>]d<SIZE> | <MOD>")
}
func rollDie(size int) int {
@@ -22,39 +25,75 @@ func rollDie(size int) int {
return int(num.Int64()) + 1
}
-func roll(input string) {
- parser := regexp.MustCompile("^([0-9]*)d([0-9]+)([+-][0-9]+)?$")
- parts := parser.FindStringSubmatch(input)
- if len(parts) < 2 {
+var parser = regexp.MustCompile("^(([0-9]*)d)?([0-9]+)$")
+
+func rollSpec(spec string) (string, int) {
+ parts := parser.FindStringSubmatch(spec)
+ if len(parts) < 4 {
usage()
- return
- }
- dice, _ := strconv.Atoi(parts[1])
- die_size, _ := strconv.Atoi(parts[2])
- mod := 0
- if len(parts) > 3 {
- mod, _ = strconv.Atoi(parts[3])
+ os.Exit(1)
}
- if dice < 1 {
- dice = 1
+
+ var str string
+ var num int
+ if parts[1] == "" {
+ str = parts[3]
+ num, _ = strconv.Atoi(str)
+ } else {
+ dice, _ := strconv.Atoi(parts[2])
+ die_size, _ := strconv.Atoi(parts[3])
+ if dice < 1 {
+ dice = 1
+ }
+
+ var rolls []string
+ for i := 0; i < dice; i++ {
+ v := rollDie(die_size)
+ rolls = append(rolls, strconv.Itoa(v))
+ num += v
+ }
+ str = "(" + strings.Join(rolls, "+") + ")"
}
+ return str, num
+}
+
+func roll(speclist string) {
+ var strs []string
+ var total int
- total := 0
- for i := 0; i < dice; i++ {
- v := rollDie(die_size)
- fmt.Printf("%d+", v)
- total += v
+ neg := strings.HasPrefix(speclist, "-")
+ speclist = strings.TrimPrefix(speclist, "-")
+ for {
+ sep := strings.IndexAny(speclist, "+-")
+ var spec string
+ if sep < 0 {
+ spec = speclist
+ } else {
+ spec = speclist[:sep]
+ }
+ str, num := rollSpec(spec)
+ if neg {
+ str = "-" + str
+ num = -num
+ }
+ strs = append(strs, str)
+ total += num
+
+ if sep < 0 {
+ break
+ }
+ neg = speclist[sep] == '-'
+ speclist = speclist[sep+1:]
}
- total += mod
- fmt.Printf("%d = %d\n", mod, total)
+
+ fmt.Printf("%s = %d\n", strings.Join(strs, " + "), total)
}
func main() {
- if len(os.Args) == 1 {
+ if len(os.Args) < 2 {
usage()
}
- args := os.Args[1:]
- for _, arg := range args {
+ for _, arg := range os.Args[1:] {
roll(arg)
}
}