diff options
-rw-r--r-- | roll.go | 87 |
1 files changed, 63 insertions, 24 deletions
@@ -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) } } |