-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroll.go
85 lines (74 loc) · 2.01 KB
/
roll.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package diceprob
import (
"strconv"
"strings"
)
// Roll - Roll a random value for the Expression; top-level of the recursive roll functions.
func (e *Expression) Roll() int64 {
left := e.Left.Roll()
for _, right := range e.Right {
left = right.Operator.Roll(left, right.Term.Roll())
}
return left
}
// Roll - Roll a random values around the Operator; part of the recursive roll functions.
func (o Operator) Roll(left, right int64) int64 {
switch o {
case OpMul:
return left * right
case OpDiv:
return left / right
case OpAdd:
return left + right
case OpSub:
return left - right
}
panic("unsupported operator") // TODO - We can do better here.
}
// Roll - Roll a random value for the Term; part of the recursive roll functions.
func (t *Term) Roll() int64 {
left := t.Left.Roll()
for _, right := range t.Right {
left = right.Operator.Roll(left, right.Atom.Roll())
}
return left
}
// Roll - Roll a random value for the Atom; part of the recursive roll functions.
func (a *Atom) Roll() int64 {
switch {
case a.Modifier != nil:
return *a.Modifier
case a.RollExpr != nil:
return a.RollExpr.Roll()
default:
return a.SubExpression.Roll()
}
}
// Roll - Roll a random value for the DiceRoll; deepest of the recursive roll functions.
func (s *DiceRoll) Roll() int64 {
// Convert s to a string.
sActual := strings.ToLower(string(*s))
// Find the D in the roll.
dToken := strings.Index(sActual, "d")
if dToken == -1 {
panic("invalid dice roll atomic expression")
}
// Grab the digits to the right of the D.
right, err := strconv.ParseInt(sActual[dToken+1:], 10, 64)
if err != nil {
panic(err)
}
// If the dice roll is a "middle" roll of 3 dice.
if sActual[0:3] == "mid" {
// Return a middle rolled value.
return rollIt("m", 3, right)
}
// Not a "middle" roll, therefore a standard roll.
// Grab the number of dice from the left of the D.
left, err := strconv.ParseInt(sActual[0:dToken], 10, 64)
if err != nil {
panic(err)
}
// Return a standard rolled value.
return rollIt("d", left, right)
}