93 lines
1.6 KiB
Go
93 lines
1.6 KiB
Go
|
package dice
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
type VsRoller struct{}
|
||
|
|
||
|
var vsPattern = regexp.MustCompile(`([0-9]+)d([0-9]+)(e|r)?v([0-9]+)($|\s)`)
|
||
|
|
||
|
func (VsRoller) Pattern() *regexp.Regexp { return vsPattern }
|
||
|
|
||
|
type VsResult struct {
|
||
|
basicRollResult
|
||
|
Rolls []int
|
||
|
Successes int
|
||
|
}
|
||
|
|
||
|
func (r VsResult) Description() string { return r.desc }
|
||
|
|
||
|
func (r VsResult) String() string {
|
||
|
return fmt.Sprintf("%d %v", r.Successes, r.Rolls)
|
||
|
}
|
||
|
|
||
|
func (r VsResult) Int() int {
|
||
|
return r.Successes
|
||
|
}
|
||
|
|
||
|
func (VsRoller) Roll(matches []string) (RollResult, error) {
|
||
|
dice, err := strconv.ParseInt(matches[1], 10, 0)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if dice < 1 {
|
||
|
return nil, errors.New("Count must be 1 or more")
|
||
|
}
|
||
|
|
||
|
sides, err := strconv.ParseInt(matches[2], 10, 0)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if sides < 2 {
|
||
|
return nil, errors.New("Sides must be 2 or more")
|
||
|
}
|
||
|
|
||
|
explode := matches[3] == "e"
|
||
|
reroll := matches[3] == "r"
|
||
|
|
||
|
target, err := strconv.ParseInt(matches[4], 10, 0)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
result := VsResult{
|
||
|
basicRollResult: basicRollResult{matches[0]},
|
||
|
Rolls: make([]int, 0, dice),
|
||
|
Successes: 0,
|
||
|
}
|
||
|
|
||
|
for i := int64(0); i < dice; i++ {
|
||
|
roll := rand.Intn(int(sides)) + 1
|
||
|
|
||
|
if roll == int(sides) && explode {
|
||
|
total := roll
|
||
|
for roll == int(sides) {
|
||
|
roll = rand.Intn(int(sides)) + 1
|
||
|
total += roll
|
||
|
}
|
||
|
roll = total
|
||
|
}
|
||
|
|
||
|
if roll == int(sides) && reroll {
|
||
|
i--
|
||
|
}
|
||
|
|
||
|
if roll >= int(target) {
|
||
|
result.Successes += 1
|
||
|
}
|
||
|
|
||
|
result.Rolls = append(result.Rolls, roll)
|
||
|
}
|
||
|
|
||
|
return result, nil
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
addRollHandler(VsRoller{})
|
||
|
}
|