games_dice 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +38 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +41 -3
- data/.yardopts +1 -1
- data/CHANGELOG.md +12 -0
- data/Gemfile +10 -0
- data/README.md +11 -33
- data/Rakefile +2 -18
- data/ext/games_dice/games_dice.c +1 -1
- data/ext/games_dice/probabilities.c +127 -8
- data/ext/games_dice/probabilities.h +1 -1
- data/games_dice.gemspec +11 -19
- data/lib/games_dice/bunch.rb +27 -65
- data/lib/games_dice/bunch_helpers.rb +68 -0
- data/lib/games_dice/complex_die.rb +10 -146
- data/lib/games_dice/complex_die_helpers.rb +238 -46
- data/lib/games_dice/dice.rb +17 -10
- data/lib/games_dice/die.rb +2 -2
- data/lib/games_dice/die_result.rb +84 -71
- data/lib/games_dice/marshal.rb +26 -3
- data/lib/games_dice/parser.rb +128 -102
- data/lib/games_dice/version.rb +2 -1
- data/lib/games_dice.rb +7 -9
- data/spec/bunch_spec.rb +72 -72
- data/spec/complex_die_spec.rb +158 -158
- data/spec/dice_spec.rb +5 -5
- data/spec/die_result_spec.rb +98 -98
- data/spec/die_spec.rb +19 -19
- data/spec/helpers.rb +2 -4
- data/spec/map_rule_spec.rb +17 -17
- data/spec/parser_spec.rb +7 -7
- data/spec/probability_spec.rb +188 -196
- data/spec/readme_spec.rb +28 -22
- data/spec/reroll_rule_spec.rb +15 -15
- metadata +16 -139
- data/.travis.yml +0 -11
data/spec/complex_die_spec.rb
CHANGED
|
@@ -8,303 +8,303 @@ describe GamesDice::ComplexDie do
|
|
|
8
8
|
srand(4567)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
it '
|
|
12
|
-
die =
|
|
13
|
-
expect(die.min).to
|
|
14
|
-
expect(die.max).to
|
|
15
|
-
expect(die.sides).to
|
|
11
|
+
it 'represent a basic die as an object' do
|
|
12
|
+
die = described_class.new(6)
|
|
13
|
+
expect(die.min).to be 1
|
|
14
|
+
expect(die.max).to be 6
|
|
15
|
+
expect(die.sides).to be 6
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
it "
|
|
19
|
-
die =
|
|
18
|
+
it "return results based on Ruby's internal rand() by default" do
|
|
19
|
+
die = described_class.new(10)
|
|
20
20
|
[5, 4, 10, 4, 7, 8, 1, 9].each do |expected|
|
|
21
21
|
expect(die.roll.value).to eql expected
|
|
22
22
|
expect(die.result.value).to eql expected
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
it '
|
|
26
|
+
it 'use any object with a rand(Integer) method' do
|
|
27
27
|
prng = TestPRNG.new
|
|
28
|
-
die =
|
|
28
|
+
die = described_class.new(20, prng: prng)
|
|
29
29
|
[16, 7, 3, 11, 16, 18, 20, 7].each do |expected|
|
|
30
30
|
expect(die.roll.value).to eql expected
|
|
31
31
|
expect(die.result.value).to eql expected
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
it '
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
expect
|
|
45
|
-
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
expect
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
expect
|
|
53
|
-
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
expect
|
|
57
|
-
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
expect
|
|
61
|
-
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
expect
|
|
65
|
-
|
|
66
|
-
end
|
|
35
|
+
it 'optionally accept a rerolls param' do
|
|
36
|
+
described_class.new(10, rerolls: [])
|
|
37
|
+
described_class.new(10, rerolls: [GamesDice::RerollRule.new(6, :<=, :reroll_add)])
|
|
38
|
+
described_class.new(10,
|
|
39
|
+
rerolls: [GamesDice::RerollRule.new(6, :<=, :reroll_add),
|
|
40
|
+
GamesDice::RerollRule.new(1, :>=, :reroll_subtract)])
|
|
41
|
+
described_class.new(10, rerolls: [[6, :<=, :reroll_add]])
|
|
42
|
+
described_class.new(10, rerolls: [[6, :<=, :reroll_add], [1, :>=, :reroll_subtract]])
|
|
43
|
+
|
|
44
|
+
expect do
|
|
45
|
+
described_class.new(10, rerolls: 7)
|
|
46
|
+
end.to raise_error(TypeError)
|
|
47
|
+
|
|
48
|
+
expect do
|
|
49
|
+
described_class.new(10, rerolls: ['hello'])
|
|
50
|
+
end.to raise_error(TypeError)
|
|
51
|
+
|
|
52
|
+
expect do
|
|
53
|
+
described_class.new(10, rerolls: [GamesDice::RerollRule.new(6, :<=, :reroll_add), :reroll_add])
|
|
54
|
+
end.to raise_error(TypeError)
|
|
55
|
+
|
|
56
|
+
expect do
|
|
57
|
+
described_class.new(10, rerolls: [7])
|
|
58
|
+
end.to raise_error(TypeError)
|
|
59
|
+
|
|
60
|
+
expect do
|
|
61
|
+
described_class.new(10, rerolls: [['hello']])
|
|
62
|
+
end.to raise_error(ArgumentError)
|
|
63
|
+
|
|
64
|
+
expect do
|
|
65
|
+
described_class.new(10, rerolls: [[6, :<=, :reroll_add], :reroll_add])
|
|
66
|
+
end.to raise_error(TypeError)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
it '
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
expect
|
|
77
|
-
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
expect
|
|
81
|
-
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
expect
|
|
85
|
-
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
expect
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
expect
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
end
|
|
69
|
+
it 'optionally accept a maps param' do
|
|
70
|
+
described_class.new(10, maps: [])
|
|
71
|
+
described_class.new(10, maps: [GamesDice::MapRule.new(7, :<=, 1)])
|
|
72
|
+
described_class.new(10, maps: [GamesDice::MapRule.new(7, :<=, 1), GamesDice::MapRule.new(1, :>, -1)])
|
|
73
|
+
described_class.new(10, maps: [[7, :<=, 1]])
|
|
74
|
+
described_class.new(10, maps: [[7, :<=, 1], [1, :>, -1]])
|
|
75
|
+
|
|
76
|
+
expect do
|
|
77
|
+
described_class.new(10, maps: 7)
|
|
78
|
+
end.to raise_error(TypeError)
|
|
79
|
+
|
|
80
|
+
expect do
|
|
81
|
+
described_class.new(10, maps: [7])
|
|
82
|
+
end.to raise_error(TypeError)
|
|
83
|
+
|
|
84
|
+
expect do
|
|
85
|
+
described_class.new(10, maps: [[7]])
|
|
86
|
+
end.to raise_error(ArgumentError)
|
|
87
|
+
|
|
88
|
+
expect do
|
|
89
|
+
described_class.new(10, maps: ['hello'])
|
|
90
|
+
end.to raise_error(TypeError)
|
|
91
|
+
|
|
92
|
+
expect do
|
|
93
|
+
described_class.new(10,
|
|
94
|
+
maps: [GamesDice::MapRule.new(7, :<=, 1),
|
|
95
|
+
GamesDice::RerollRule.new(6, :<=, :reroll_add)])
|
|
96
|
+
end.to raise_error(TypeError)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
describe 'with rerolls' do
|
|
100
|
-
it '
|
|
101
|
-
die =
|
|
102
|
-
expect(die.min).to
|
|
103
|
-
expect(die.max).to
|
|
104
|
-
|
|
105
|
-
die =
|
|
106
|
-
expect(die.min).to
|
|
107
|
-
expect(die.max).to
|
|
108
|
-
|
|
109
|
-
die =
|
|
110
|
-
expect(die.min).to
|
|
111
|
-
expect(die.max).to
|
|
100
|
+
it 'calculate correct minimum and maximum results' do
|
|
101
|
+
die = described_class.new(10, rerolls: [GamesDice::RerollRule.new(10, :<=, :reroll_add, 3)])
|
|
102
|
+
expect(die.min).to be 1
|
|
103
|
+
expect(die.max).to be 40
|
|
104
|
+
|
|
105
|
+
die = described_class.new(10, rerolls: [[1, :>=, :reroll_subtract]])
|
|
106
|
+
expect(die.min).to be(-9)
|
|
107
|
+
expect(die.max).to be 10
|
|
108
|
+
|
|
109
|
+
die = described_class.new(10, rerolls: [GamesDice::RerollRule.new(10, :<=, :reroll_add)])
|
|
110
|
+
expect(die.min).to be 1
|
|
111
|
+
expect(die.max).to be 10_010
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
it '
|
|
115
|
-
die =
|
|
114
|
+
it 'simulate a d10 that rerolls and adds on a result of 10' do
|
|
115
|
+
die = described_class.new(10, rerolls: [[10, :<=, :reroll_add]])
|
|
116
116
|
[5, 4, 14, 7, 8, 1, 9].each do |expected|
|
|
117
117
|
expect(die.roll.value).to eql expected
|
|
118
118
|
expect(die.result.value).to eql expected
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
it '
|
|
123
|
-
die =
|
|
122
|
+
it 'explain how it got results outside range 1 to 10 on a d10' do
|
|
123
|
+
die = described_class.new(10, rerolls: [[10, :<=, :reroll_add], [1, :>=, :reroll_subtract]])
|
|
124
124
|
['5', '4', '[10+4] 14', '7', '8', '[1-9] -8'].each do |expected|
|
|
125
125
|
die.roll
|
|
126
126
|
expect(die.explain_result).to eql expected
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
it '
|
|
131
|
-
die =
|
|
130
|
+
it 'calculate an expected result' do
|
|
131
|
+
die = described_class.new(10, rerolls: [[10, :<=, :reroll_add], [1, :>=, :reroll_subtract]])
|
|
132
132
|
expect(die.probabilities.expected).to be_within(1e-10).of 5.5
|
|
133
133
|
|
|
134
|
-
die =
|
|
134
|
+
die = described_class.new(10, rerolls: [GamesDice::RerollRule.new(1, :<=, :reroll_use_best, 1)])
|
|
135
135
|
expect(die.probabilities.expected).to be_within(1e-10).of 7.15
|
|
136
136
|
|
|
137
|
-
die =
|
|
137
|
+
die = described_class.new(10, rerolls: [GamesDice::RerollRule.new(1, :<=, :reroll_use_worst, 2)])
|
|
138
138
|
expect(die.probabilities.expected).to be_within(1e-10).of 3.025
|
|
139
139
|
|
|
140
|
-
die =
|
|
140
|
+
die = described_class.new(6, rerolls: [GamesDice::RerollRule.new(6, :<=, :reroll_add)])
|
|
141
141
|
expect(die.probabilities.expected).to be_within(1e-10).of 4.2
|
|
142
142
|
|
|
143
|
-
die =
|
|
143
|
+
die = described_class.new(8, rerolls: [GamesDice::RerollRule.new(1, :>=, :reroll_use_best)])
|
|
144
144
|
expect(die.probabilities.expected).to be_within(1e-10).of 5.0
|
|
145
145
|
|
|
146
|
-
die =
|
|
146
|
+
die = described_class.new(4, rerolls: [GamesDice::RerollRule.new(1, :>=, :reroll_replace, 1)])
|
|
147
147
|
expect(die.probabilities.expected).to be_within(1e-10).of 2.875
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
it '
|
|
151
|
-
die =
|
|
150
|
+
it 'calculate probabilities of each possible result' do
|
|
151
|
+
die = described_class.new(6, rerolls: [GamesDice::RerollRule.new(7, :>, :reroll_add, 1)])
|
|
152
152
|
probs = die.probabilities.to_h
|
|
153
153
|
expect(probs[11]).to be_within(1e-10).of 2 / 36.0
|
|
154
154
|
expect(probs[8]).to be_within(1e-10).of 5 / 36.0
|
|
155
|
-
expect(probs.values.
|
|
155
|
+
expect(probs.values.sum).to be_within(1e-9).of 1.0
|
|
156
156
|
|
|
157
|
-
die =
|
|
157
|
+
die = described_class.new(10, rerolls: [GamesDice::RerollRule.new(10, :<=, :reroll_add)])
|
|
158
158
|
probs = die.probabilities.to_h
|
|
159
159
|
expect(probs[8]).to be_within(1e-10).of 0.1
|
|
160
160
|
expect(probs[10]).to be_nil
|
|
161
161
|
expect(probs[13]).to be_within(1e-10).of 0.01
|
|
162
162
|
expect(probs[27]).to be_within(1e-10).of 0.001
|
|
163
|
-
expect(probs.values.
|
|
163
|
+
expect(probs.values.sum).to be_within(1e-9).of 1.0
|
|
164
164
|
|
|
165
|
-
die =
|
|
165
|
+
die = described_class.new(6, rerolls: [GamesDice::RerollRule.new(1, :>=, :reroll_replace, 1)])
|
|
166
166
|
probs = die.probabilities.to_h
|
|
167
167
|
expect(probs[1]).to be_within(1e-10).of 1 / 36.0
|
|
168
168
|
expect(probs[2]).to be_within(1e-10).of 7 / 36.0
|
|
169
|
-
expect(probs.values.
|
|
169
|
+
expect(probs.values.sum).to be_within(1e-9).of 1.0
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
-
it '
|
|
173
|
-
die =
|
|
172
|
+
it 'calculate aggregate probabilities' do
|
|
173
|
+
die = described_class.new(6, rerolls: [GamesDice::RerollRule.new(7, :>, :reroll_add, 1)])
|
|
174
174
|
probs = die.probabilities
|
|
175
175
|
expect(probs.p_gt(7)).to be_within(1e-10).of 15 / 36.0
|
|
176
|
-
expect(probs.p_gt(-10)).to
|
|
177
|
-
expect(probs.p_gt(12)).to
|
|
176
|
+
expect(probs.p_gt(-10)).to be 1.0
|
|
177
|
+
expect(probs.p_gt(12)).to be 0.0
|
|
178
178
|
|
|
179
179
|
expect(probs.p_ge(7)).to be_within(1e-10).of 21 / 36.0
|
|
180
|
-
expect(probs.p_ge(2)).to
|
|
181
|
-
expect(probs.p_ge(15)).to
|
|
180
|
+
expect(probs.p_ge(2)).to be 1.0
|
|
181
|
+
expect(probs.p_ge(15)).to be 0.0
|
|
182
182
|
|
|
183
183
|
expect(probs.p_lt(7)).to be_within(1e-10).of 15 / 36.0
|
|
184
|
-
expect(probs.p_lt(-10)).to
|
|
185
|
-
expect(probs.p_lt(13)).to
|
|
184
|
+
expect(probs.p_lt(-10)).to be 0.0
|
|
185
|
+
expect(probs.p_lt(13)).to be 1.0
|
|
186
186
|
|
|
187
187
|
expect(probs.p_le(7)).to be_within(1e-10).of 21 / 36.0
|
|
188
|
-
expect(probs.p_le(1)).to
|
|
189
|
-
expect(probs.p_le(12)).to
|
|
188
|
+
expect(probs.p_le(1)).to be 0.0
|
|
189
|
+
expect(probs.p_le(12)).to be 1.0
|
|
190
190
|
end
|
|
191
191
|
end
|
|
192
192
|
|
|
193
193
|
describe 'with maps' do
|
|
194
|
-
it '
|
|
195
|
-
die =
|
|
196
|
-
expect(die.min).to
|
|
197
|
-
expect(die.max).to
|
|
194
|
+
it 'calculate correct minimum and maximum results' do
|
|
195
|
+
die = described_class.new(10, maps: [GamesDice::MapRule.new(7, :<=, 1, 'S')])
|
|
196
|
+
expect(die.min).to be 0
|
|
197
|
+
expect(die.max).to be 1
|
|
198
198
|
end
|
|
199
199
|
|
|
200
|
-
it '
|
|
201
|
-
die =
|
|
200
|
+
it 'simulate a d10 that scores 1 for success on a value of 7 or more' do
|
|
201
|
+
die = described_class.new(10, maps: [[7, :<=, 1, 'S']])
|
|
202
202
|
[0, 0, 1, 0, 1, 1, 0, 1].each do |expected|
|
|
203
203
|
expect(die.roll.value).to eql expected
|
|
204
204
|
expect(die.result.value).to eql expected
|
|
205
205
|
end
|
|
206
206
|
end
|
|
207
207
|
|
|
208
|
-
it '
|
|
209
|
-
die =
|
|
208
|
+
it 'label the mappings applied with the provided names' do
|
|
209
|
+
die = described_class.new(10, maps: [[7, :<=, 1, 'S'], [1, :>=, -1, 'F']])
|
|
210
210
|
['5', '4', '10 S', '4', '7 S', '8 S', '1 F', '9 S'].each do |expected|
|
|
211
211
|
die.roll
|
|
212
212
|
expect(die.explain_result).to eql expected
|
|
213
213
|
end
|
|
214
214
|
end
|
|
215
215
|
|
|
216
|
-
it '
|
|
217
|
-
die =
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
it 'calculate an expected result' do
|
|
217
|
+
die = described_class.new(10,
|
|
218
|
+
maps: [GamesDice::MapRule.new(7, :<=, 1, 'S'),
|
|
219
|
+
GamesDice::MapRule.new(1, :>=, -1, 'F')])
|
|
220
220
|
expect(die.probabilities.expected).to be_within(1e-10).of 0.3
|
|
221
221
|
end
|
|
222
222
|
|
|
223
|
-
it '
|
|
224
|
-
die =
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
it 'calculate probabilities of each possible result' do
|
|
224
|
+
die = described_class.new(10,
|
|
225
|
+
maps: [GamesDice::MapRule.new(7, :<=, 1, 'S'),
|
|
226
|
+
GamesDice::MapRule.new(1, :>=, -1, 'F')])
|
|
227
227
|
probs_hash = die.probabilities.to_h
|
|
228
228
|
expect(probs_hash[1]).to be_within(1e-10).of 0.4
|
|
229
229
|
expect(probs_hash[0]).to be_within(1e-10).of 0.5
|
|
230
230
|
expect(probs_hash[-1]).to be_within(1e-10).of 0.1
|
|
231
|
-
expect(probs_hash.values.
|
|
231
|
+
expect(probs_hash.values.sum).to be_within(1e-9).of 1.0
|
|
232
232
|
end
|
|
233
233
|
|
|
234
|
-
it '
|
|
235
|
-
die =
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
it 'calculate aggregate probabilities' do
|
|
235
|
+
die = described_class.new(10,
|
|
236
|
+
maps: [GamesDice::MapRule.new(7, :<=, 1, 'S'),
|
|
237
|
+
GamesDice::MapRule.new(1, :>=, -1, 'F')])
|
|
238
238
|
probs = die.probabilities
|
|
239
|
-
expect(probs.p_gt(-2)).to
|
|
239
|
+
expect(probs.p_gt(-2)).to be 1.0
|
|
240
240
|
expect(probs.p_gt(-1)).to be_within(1e-10).of 0.9
|
|
241
|
-
expect(probs.p_gt(1)).to
|
|
241
|
+
expect(probs.p_gt(1)).to be 0.0
|
|
242
242
|
|
|
243
243
|
expect(probs.p_ge(1)).to be_within(1e-10).of 0.4
|
|
244
|
-
expect(probs.p_ge(-1)).to
|
|
245
|
-
expect(probs.p_ge(2)).to
|
|
244
|
+
expect(probs.p_ge(-1)).to be 1.0
|
|
245
|
+
expect(probs.p_ge(2)).to be 0.0
|
|
246
246
|
|
|
247
247
|
expect(probs.p_lt(1)).to be_within(1e-10).of 0.6
|
|
248
|
-
expect(probs.p_lt(-1)).to
|
|
249
|
-
expect(probs.p_lt(2)).to
|
|
248
|
+
expect(probs.p_lt(-1)).to be 0.0
|
|
249
|
+
expect(probs.p_lt(2)).to be 1.0
|
|
250
250
|
|
|
251
251
|
expect(probs.p_le(-1)).to be_within(1e-10).of 0.1
|
|
252
|
-
expect(probs.p_le(-2)).to
|
|
253
|
-
expect(probs.p_le(1)).to
|
|
252
|
+
expect(probs.p_le(-2)).to be 0.0
|
|
253
|
+
expect(probs.p_le(1)).to be 1.0
|
|
254
254
|
end
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
describe 'with rerolls and maps together' do
|
|
258
258
|
before do
|
|
259
|
-
@die =
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
@die = described_class.new(6,
|
|
260
|
+
rerolls: [[6, :<=, :reroll_add]],
|
|
261
|
+
maps: [GamesDice::MapRule.new(9, :<=, 1, 'Success')])
|
|
262
262
|
end
|
|
263
263
|
|
|
264
|
-
it '
|
|
265
|
-
expect(@die.min).to
|
|
266
|
-
expect(@die.max).to
|
|
264
|
+
it 'calculate correct minimum and maximum results' do
|
|
265
|
+
expect(@die.min).to be 0
|
|
266
|
+
expect(@die.max).to be 1
|
|
267
267
|
end
|
|
268
268
|
|
|
269
|
-
it '
|
|
269
|
+
it 'calculate an expected result' do
|
|
270
270
|
expect(@die.probabilities.expected).to be_within(1e-10).of 4 / 36.0
|
|
271
271
|
end
|
|
272
272
|
|
|
273
|
-
it '
|
|
273
|
+
it 'calculate probabilities of each possible result' do
|
|
274
274
|
probs_hash = @die.probabilities.to_h
|
|
275
275
|
expect(probs_hash[1]).to be_within(1e-10).of 4 / 36.0
|
|
276
276
|
expect(probs_hash[0]).to be_within(1e-10).of 32 / 36.0
|
|
277
|
-
expect(probs_hash.values.
|
|
277
|
+
expect(probs_hash.values.sum).to be_within(1e-9).of 1.0
|
|
278
278
|
end
|
|
279
279
|
|
|
280
|
-
it '
|
|
280
|
+
it 'calculate aggregate probabilities' do
|
|
281
281
|
probs = @die.probabilities
|
|
282
282
|
|
|
283
283
|
expect(probs.p_gt(0)).to be_within(1e-10).of 4 / 36.0
|
|
284
|
-
expect(probs.p_gt(-2)).to
|
|
285
|
-
expect(probs.p_gt(1)).to
|
|
284
|
+
expect(probs.p_gt(-2)).to be 1.0
|
|
285
|
+
expect(probs.p_gt(1)).to be 0.0
|
|
286
286
|
|
|
287
287
|
expect(probs.p_ge(1)).to be_within(1e-10).of 4 / 36.0
|
|
288
|
-
expect(probs.p_ge(-1)).to
|
|
289
|
-
expect(probs.p_ge(2)).to
|
|
288
|
+
expect(probs.p_ge(-1)).to be 1.0
|
|
289
|
+
expect(probs.p_ge(2)).to be 0.0
|
|
290
290
|
|
|
291
291
|
expect(probs.p_lt(1)).to be_within(1e-10).of 32 / 36.0
|
|
292
|
-
expect(probs.p_lt(0)).to
|
|
293
|
-
expect(probs.p_lt(2)).to
|
|
292
|
+
expect(probs.p_lt(0)).to be 0.0
|
|
293
|
+
expect(probs.p_lt(2)).to be 1.0
|
|
294
294
|
|
|
295
295
|
expect(probs.p_le(0)).to be_within(1e-10).of 32 / 36.0
|
|
296
|
-
expect(probs.p_le(-1)).to
|
|
297
|
-
expect(probs.p_le(1)).to
|
|
296
|
+
expect(probs.p_le(-1)).to be 0.0
|
|
297
|
+
expect(probs.p_le(1)).to be 1.0
|
|
298
298
|
end
|
|
299
299
|
|
|
300
|
-
it '
|
|
300
|
+
it 'apply mapping to final re-rolled result' do
|
|
301
301
|
[0, 1, 0, 0].each do |expected|
|
|
302
302
|
expect(@die.roll.value).to eql expected
|
|
303
303
|
expect(@die.result.value).to eql expected
|
|
304
304
|
end
|
|
305
305
|
end
|
|
306
306
|
|
|
307
|
-
it '
|
|
307
|
+
it 'explain how it got each result' do
|
|
308
308
|
['5', '[6+4] 10 Success', '[6+2] 8', '5'].each do |expected|
|
|
309
309
|
@die.roll
|
|
310
310
|
expect(@die.explain_result).to eql expected
|
data/spec/dice_spec.rb
CHANGED
|
@@ -4,14 +4,14 @@ require 'helpers'
|
|
|
4
4
|
|
|
5
5
|
describe GamesDice::Dice do
|
|
6
6
|
describe 'dice scheme' do
|
|
7
|
-
before
|
|
7
|
+
before do
|
|
8
8
|
srand(67_809)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe '1d10+2' do
|
|
12
|
-
let(:dice) {
|
|
12
|
+
let(:dice) { described_class.new([{ sides: 10, ndice: 1 }], 2) }
|
|
13
13
|
|
|
14
|
-
it '
|
|
14
|
+
it 'simulate rolling a ten-sided die, and adding two to each result' do
|
|
15
15
|
[5, 4, 10, 10, 7, 5, 9].each do |expected_total|
|
|
16
16
|
expect(dice.roll).to eql expected_total
|
|
17
17
|
expect(dice.result).to eql expected_total
|
|
@@ -20,9 +20,9 @@ describe GamesDice::Dice do
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
describe '2d6+6' do
|
|
23
|
-
let(:dice) {
|
|
23
|
+
let(:dice) { described_class.new([{ sides: 6, ndice: 2 }], 6) }
|
|
24
24
|
|
|
25
|
-
it '
|
|
25
|
+
it 'simulate rolling two six-sided dice and adding six to the result' do
|
|
26
26
|
[15, 12, 17, 15, 13, 13, 16].each do |expected_total|
|
|
27
27
|
expect(dice.roll).to eql expected_total
|
|
28
28
|
expect(dice.result).to eql expected_total
|