From 76cecfa4d41e1c8d32e2be194b2ccd1007a820b4 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 26 Jan 2017 02:24:39 -0500 Subject: roll: Support more complex rolls. --- roll.go | 87 +++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 24 deletions(-) (limited to 'roll.go') 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 []d[+]\n") + fmt.Printf("Usage: %s ...\n", os.Args[0]) + fmt.Println("SPECLIST = [-]SPEC[<<+|->SPEC>...]") + fmt.Println("SPEC = []d | ") } 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) } } -- cgit v1.2.3