Go binary/server for helping run/build sessions for the Maze Rats TTRPG
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

104 lines
2.1 KiB

package dice
import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"regexp"
"strconv"
"strings"
)
type diceRequest struct {
count int
diceType int
}
type DiceRoller interface {
Roll(request string) ([]int, error)
TableRoll() [2]int
}
type Roller struct {
Rand *rand.Rand
Seed int64
DiceRoller
}
func NewRoller(seed int64) *Roller {
return &Roller{
Rand: rand.New(rand.NewSource(seed)),
Seed: seed,
}
}
// RollToJSON takes a []int and returns JSON with those ints in "results"
func RollToJSON(rolls []int) ([]byte, error) {
result := struct {
Results []int `json:"results"`
}{
Results: rolls,
}
jsonResults, err := json.Marshal(result)
if err != nil {
return []byte{}, err
}
return jsonResults, nil
}
// RollToText takes a []int and returns them a spaced separated string
func RollToText(rolls []int) string {
results := []string{}
for _, r := range rolls {
results = append(results, strconv.Itoa(r))
}
response := strings.Join(results, " ")
response = response + "\n"
return response
}
// Roll takes a string in the format of "XdY" and returns []int for its results
func (r *Roller) Roll(request string) ([]int, error) {
var result []int
diceRequest, err := parseRoll(request)
if err != nil {
return result, err
}
for i := 1; i <= diceRequest.count; i++ {
result = append(result, r.Rand.Intn(diceRequest.diceType)+1)
}
return result, nil
}
// TableRoll returns a roll used for selecting an item on a Maze Rats table
func (r *Roller) TableRoll() [2]int {
result, _ := r.Roll("2d6")
return [2]int{result[0], result[1]}
}
func parseRoll(request string) (diceRequest, error) {
regexString := "[1-9][0-9]*d[1-9]+"
diceRegEx := regexp.MustCompile(regexString)
correctRequest := diceRegEx.Match([]byte(request))
if !correctRequest {
errMsg := fmt.Sprintf("Must pass string matching '%v' "+
"you passed '%v'",
regexString, request)
return diceRequest{}, errors.New(errMsg)
}
var parsedRequest []string = strings.Split(request, "d")
count, _ := strconv.Atoi(parsedRequest[0])
diceType, _ := strconv.Atoi(parsedRequest[1])
return diceRequest{
count: count,
diceType: diceType,
}, nil
}