games_dice 0.0.3 → 0.0.5
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.
- data/games_dice.gemspec +4 -2
- data/lib/games_dice.rb +3 -0
- data/lib/games_dice/bunch.rb +275 -320
- data/lib/games_dice/complex_die.rb +226 -269
- data/lib/games_dice/constants.rb +16 -0
- data/lib/games_dice/dice.rb +43 -0
- data/lib/games_dice/die.rb +58 -92
- data/lib/games_dice/die_result.rb +3 -15
- data/lib/games_dice/map_rule.rb +41 -43
- data/lib/games_dice/probabilities.rb +97 -0
- data/lib/games_dice/reroll_rule.rb +41 -58
- data/lib/games_dice/version.rb +1 -1
- data/spec/bunch_spec.rb +196 -188
- data/spec/complex_die_spec.rb +77 -68
- data/spec/dice_spec.rb +34 -0
- data/spec/die_spec.rb +25 -29
- data/spec/probability_spec.rb +265 -0
- metadata +31 -8
data/lib/games_dice/version.rb
CHANGED
data/spec/bunch_spec.rb
CHANGED
@@ -9,95 +9,97 @@ describe GamesDice::Bunch do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '1d10' do
|
12
|
-
let(:
|
12
|
+
let(:bunch) { GamesDice::Bunch.new( :sides => 10, :ndice => 1 ) }
|
13
13
|
|
14
14
|
it "should simulate rolling a ten-sided die" do
|
15
15
|
[3,2,8,8,5,3,7].each do |expected_total|
|
16
|
-
|
17
|
-
|
16
|
+
bunch.roll.should == expected_total
|
17
|
+
bunch.result.should == expected_total
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should concisely explain each result" do
|
22
22
|
["3", "2", "8", "8"].each do |expected_explain|
|
23
|
-
|
24
|
-
|
23
|
+
bunch.roll
|
24
|
+
bunch.explain_result.should == expected_explain
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should calculate correct min, max = 1,10" do
|
29
|
-
|
30
|
-
|
29
|
+
bunch.min.should == 1
|
30
|
+
bunch.max.should == 10
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should have a mean value of 5.5" do
|
34
|
-
|
34
|
+
bunch.probabilities.expected.should be_within(1e-10).of 5.5
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should calculate probabilities correctly" do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
prob_hash = bunch.probabilities.to_h
|
39
|
+
prob_hash[1].should be_within(1e-10).of 0.1
|
40
|
+
prob_hash[2].should be_within(1e-10).of 0.1
|
41
|
+
prob_hash[3].should be_within(1e-10).of 0.1
|
42
|
+
prob_hash[4].should be_within(1e-10).of 0.1
|
43
|
+
prob_hash[5].should be_within(1e-10).of 0.1
|
44
|
+
prob_hash[6].should be_within(1e-10).of 0.1
|
45
|
+
prob_hash[7].should be_within(1e-10).of 0.1
|
46
|
+
prob_hash[8].should be_within(1e-10).of 0.1
|
47
|
+
prob_hash[9].should be_within(1e-10).of 0.1
|
48
|
+
prob_hash[10].should be_within(1e-10).of 0.1
|
49
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
52
53
|
describe '2d6' do
|
53
|
-
let(:
|
54
|
+
let(:bunch) { GamesDice::Bunch.new( :sides => 6, :ndice => 2 ) }
|
54
55
|
|
55
56
|
it "should simulate rolling two six-sided dice and adding them" do
|
56
57
|
[9,6,11,9,7,7,10].each do |expected_total|
|
57
|
-
|
58
|
-
|
58
|
+
bunch.roll.should == expected_total
|
59
|
+
bunch.result.should == expected_total
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
63
|
it "should concisely explain each result" do
|
63
64
|
["3 + 6 = 9","2 + 4 = 6","5 + 6 = 11","3 + 6 = 9","2 + 5 = 7","6 + 1 = 7","5 + 5 = 10",].each do |expected_explain|
|
64
|
-
|
65
|
-
|
65
|
+
bunch.roll
|
66
|
+
bunch.explain_result.should == expected_explain
|
66
67
|
end
|
67
68
|
end
|
68
69
|
|
69
70
|
it "should calculate correct min, max = 2,12" do
|
70
|
-
|
71
|
-
|
71
|
+
bunch.min.should == 2
|
72
|
+
bunch.max.should == 12
|
72
73
|
end
|
73
74
|
|
74
75
|
it "should have a mean value of 7.0" do
|
75
|
-
|
76
|
+
bunch.probabilities.expected.should be_within(1e-10).of 7.0
|
76
77
|
end
|
77
78
|
|
78
79
|
it "should calculate probabilities correctly" do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
80
|
+
prob_hash = bunch.probabilities.to_h
|
81
|
+
prob_hash[2].should be_within(1e-10).of 1/36.0
|
82
|
+
prob_hash[3].should be_within(1e-10).of 2/36.0
|
83
|
+
prob_hash[4].should be_within(1e-10).of 3/36.0
|
84
|
+
prob_hash[5].should be_within(1e-10).of 4/36.0
|
85
|
+
prob_hash[6].should be_within(1e-10).of 5/36.0
|
86
|
+
prob_hash[7].should be_within(1e-10).of 6/36.0
|
87
|
+
prob_hash[8].should be_within(1e-10).of 5/36.0
|
88
|
+
prob_hash[9].should be_within(1e-10).of 4/36.0
|
89
|
+
prob_hash[10].should be_within(1e-10).of 3/36.0
|
90
|
+
prob_hash[11].should be_within(1e-10).of 2/36.0
|
91
|
+
prob_hash[12].should be_within(1e-10).of 1/36.0
|
92
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
91
93
|
end
|
92
94
|
end
|
93
95
|
|
94
96
|
describe '20d10' do
|
95
|
-
let(:
|
97
|
+
let(:bunch) { GamesDice::Bunch.new( :sides => 10, :ndice => 20 ) }
|
96
98
|
|
97
99
|
it "should simulate rolling twenty ten-sided dice and adding them" do
|
98
100
|
[132,103,102,124,132,96,111].each do |expected_total|
|
99
|
-
|
100
|
-
|
101
|
+
bunch.roll.should == expected_total
|
102
|
+
bunch.result.should == expected_total
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
@@ -106,34 +108,35 @@ describe GamesDice::Bunch do
|
|
106
108
|
"3 + 9 + 1 + 4 + 3 + 5 + 7 + 1 + 10 + 4 + 7 + 7 + 6 + 5 + 2 + 7 + 4 + 9 + 7 + 2 = 103",
|
107
109
|
"6 + 1 + 1 + 3 + 1 + 4 + 9 + 6 + 3 + 10 + 9 + 10 + 8 + 4 + 1 + 4 + 2 + 1 + 10 + 9 = 102",
|
108
110
|
].each do |expected_explain|
|
109
|
-
|
110
|
-
|
111
|
+
bunch.roll
|
112
|
+
bunch.explain_result.should == expected_explain
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
114
116
|
it "should calculate correct min, max = 20,200" do
|
115
|
-
|
116
|
-
|
117
|
+
bunch.min.should == 20
|
118
|
+
bunch.max.should == 200
|
117
119
|
end
|
118
120
|
|
119
121
|
it "should have a mean value of 110.0" do
|
120
|
-
|
122
|
+
bunch.probabilities.expected.should be_within(1e-8).of 110.0
|
121
123
|
end
|
122
124
|
|
123
125
|
it "should calculate probabilities correctly" do
|
124
|
-
|
125
|
-
|
126
|
-
|
126
|
+
prob_hash = bunch.probabilities.to_h
|
127
|
+
prob_hash[20].should be_within(1e-26).of 1e-20
|
128
|
+
prob_hash[110].should be_within(1e-10).of 0.0308191892
|
129
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
127
130
|
end
|
128
131
|
end
|
129
132
|
|
130
133
|
describe '4d6 keep best 3' do
|
131
|
-
let(:
|
134
|
+
let(:bunch) { GamesDice::Bunch.new( :sides => 6, :ndice => 4, :keep_mode => :keep_best, :keep_number => 3 ) }
|
132
135
|
|
133
136
|
it "should simulate rolling four six-sided dice and adding the best three values" do
|
134
137
|
[13,17,13,12,13,10,14].each do |expected_total|
|
135
|
-
|
136
|
-
|
138
|
+
bunch.roll.should == expected_total
|
139
|
+
bunch.result.should == expected_total
|
137
140
|
end
|
138
141
|
end
|
139
142
|
|
@@ -143,48 +146,49 @@ describe GamesDice::Bunch do
|
|
143
146
|
"2, 5, 6, 1. Keep: 2 + 5 + 6 = 13",
|
144
147
|
"5, 5, 2, 1. Keep: 2 + 5 + 5 = 12",
|
145
148
|
].each do |expected_explain|
|
146
|
-
|
147
|
-
|
149
|
+
bunch.roll
|
150
|
+
bunch.explain_result.should == expected_explain
|
148
151
|
end
|
149
152
|
end
|
150
153
|
|
151
154
|
it "should calculate correct min, max = 3,18" do
|
152
|
-
|
153
|
-
|
155
|
+
bunch.min.should == 3
|
156
|
+
bunch.max.should == 18
|
154
157
|
end
|
155
158
|
|
156
159
|
it "should have a mean value of roughly 12.2446" do
|
157
|
-
|
160
|
+
bunch.probabilities.expected.should be_within(1e-9).of 12.244598765
|
158
161
|
end
|
159
162
|
|
160
163
|
it "should calculate probabilities correctly" do
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
164
|
+
prob_hash = bunch.probabilities.to_h
|
165
|
+
prob_hash[3].should be_within(1e-10).of 1/1296.0
|
166
|
+
prob_hash[4].should be_within(1e-10).of 4/1296.0
|
167
|
+
prob_hash[5].should be_within(1e-10).of 10/1296.0
|
168
|
+
prob_hash[6].should be_within(1e-10).of 21/1296.0
|
169
|
+
prob_hash[7].should be_within(1e-10).of 38/1296.0
|
170
|
+
prob_hash[8].should be_within(1e-10).of 62/1296.0
|
171
|
+
prob_hash[9].should be_within(1e-10).of 91/1296.0
|
172
|
+
prob_hash[10].should be_within(1e-10).of 122/1296.0
|
173
|
+
prob_hash[11].should be_within(1e-10).of 148/1296.0
|
174
|
+
prob_hash[12].should be_within(1e-10).of 167/1296.0
|
175
|
+
prob_hash[13].should be_within(1e-10).of 172/1296.0
|
176
|
+
prob_hash[14].should be_within(1e-10).of 160/1296.0
|
177
|
+
prob_hash[15].should be_within(1e-10).of 131/1296.0
|
178
|
+
prob_hash[16].should be_within(1e-10).of 94/1296.0
|
179
|
+
prob_hash[17].should be_within(1e-10).of 54/1296.0
|
180
|
+
prob_hash[18].should be_within(1e-10).of 21/1296.0
|
181
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
178
182
|
end
|
179
183
|
end
|
180
184
|
|
181
185
|
describe '10d10 keep worst one' do
|
182
|
-
let(:
|
186
|
+
let(:bunch) { GamesDice::Bunch.new( :sides => 10, :ndice => 10, :keep_mode => :keep_worst, :keep_number => 1 ) }
|
183
187
|
|
184
188
|
it "should simulate rolling ten ten-sided dice and keeping the worst value" do
|
185
189
|
[2,5,1,2,1,1,2].each do |expected_total|
|
186
|
-
|
187
|
-
|
190
|
+
bunch.roll.should == expected_total
|
191
|
+
bunch.result.should == expected_total
|
188
192
|
end
|
189
193
|
end
|
190
194
|
|
@@ -194,37 +198,38 @@ describe GamesDice::Bunch do
|
|
194
198
|
"3, 9, 1, 4, 3, 5, 7, 1, 10, 4. Keep: 1",
|
195
199
|
"7, 7, 6, 5, 2, 7, 4, 9, 7, 2. Keep: 2",
|
196
200
|
].each do |expected_explain|
|
197
|
-
|
198
|
-
|
201
|
+
bunch.roll
|
202
|
+
bunch.explain_result.should == expected_explain
|
199
203
|
end
|
200
204
|
end
|
201
205
|
|
202
206
|
it "should calculate correct min, max = 1,10" do
|
203
|
-
|
204
|
-
|
207
|
+
bunch.min.should == 1
|
208
|
+
bunch.max.should == 10
|
205
209
|
end
|
206
210
|
|
207
211
|
it "should have a mean value of roughly 1.491" do
|
208
|
-
|
212
|
+
bunch.probabilities.expected.should be_within(1e-9).of 1.4914341925
|
209
213
|
end
|
210
214
|
|
211
215
|
it "should calculate probabilities correctly" do
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
216
|
+
prob_hash = bunch.probabilities.to_h
|
217
|
+
prob_hash[1].should be_within(1e-10).of 0.6513215599
|
218
|
+
prob_hash[2].should be_within(1e-10).of 0.2413042577
|
219
|
+
prob_hash[3].should be_within(1e-10).of 0.0791266575
|
220
|
+
prob_hash[4].should be_within(1e-10).of 0.0222009073
|
221
|
+
prob_hash[5].should be_within(1e-10).of 0.0050700551
|
222
|
+
prob_hash[6].should be_within(1e-10).of 0.0008717049
|
223
|
+
prob_hash[7].should be_within(1e-10).of 0.0000989527
|
224
|
+
prob_hash[8].should be_within(1e-10).of 0.0000058025
|
225
|
+
prob_hash[9].should be_within(1e-10).of 0.0000001023
|
226
|
+
prob_hash[10].should be_within(1e-18).of 1e-10
|
227
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
223
228
|
end
|
224
229
|
end
|
225
230
|
|
226
231
|
describe '5d10, re-roll and add on 10s, keep best 2' do
|
227
|
-
let(:
|
232
|
+
let(:bunch) {
|
228
233
|
GamesDice::Bunch.new(
|
229
234
|
:sides => 10, :ndice => 5, :keep_mode => :keep_best, :keep_number => 2,
|
230
235
|
:rerolls => [GamesDice::RerollRule.new(10,:==,:reroll_add)]
|
@@ -232,8 +237,8 @@ describe GamesDice::Bunch do
|
|
232
237
|
|
233
238
|
it "should simulate rolling five ten-sided 'exploding' dice and adding the best two values" do
|
234
239
|
[16,24,17,28,12,21,16].each do |expected_total|
|
235
|
-
|
236
|
-
|
240
|
+
bunch.roll.should == expected_total
|
241
|
+
bunch.result.should == expected_total
|
237
242
|
end
|
238
243
|
end
|
239
244
|
|
@@ -243,56 +248,57 @@ describe GamesDice::Bunch do
|
|
243
248
|
"6, 9, 5, 5, 8. Keep: 8 + 9 = 17",
|
244
249
|
"[10+9] 19, 5, 9, 3, 9. Keep: 9 + 19 = 28",
|
245
250
|
].each do |expected_explain|
|
246
|
-
|
247
|
-
|
251
|
+
bunch.roll
|
252
|
+
bunch.explain_result.should == expected_explain
|
248
253
|
end
|
249
254
|
end
|
250
255
|
|
251
256
|
it "should calculate correct min, max = 2, > 100" do
|
252
|
-
|
253
|
-
|
257
|
+
bunch.min.should == 2
|
258
|
+
bunch.max.should > 100
|
254
259
|
end
|
255
260
|
|
256
261
|
it "should have a mean value of roughly 18.986" do
|
257
262
|
pending "Too slow"
|
258
|
-
|
263
|
+
bunch.probabilities.expected.should be_within(1e-9).of 18.9859925804
|
259
264
|
end
|
260
265
|
|
261
266
|
it "should calculate probabilities correctly" do
|
262
267
|
pending "Too slow"
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
268
|
+
prob_hash = bunch.probabilities.to_h
|
269
|
+
prob_hash[2].should be_within(1e-10).of 0.00001
|
270
|
+
prob_hash[3].should be_within(1e-10).of 0.00005
|
271
|
+
prob_hash[4].should be_within(1e-10).of 0.00031
|
272
|
+
prob_hash[5].should be_within(1e-10).of 0.00080
|
273
|
+
prob_hash[6].should be_within(1e-10).of 0.00211
|
274
|
+
prob_hash[7].should be_within(1e-10).of 0.00405
|
275
|
+
prob_hash[8].should be_within(1e-10).of 0.00781
|
276
|
+
prob_hash[9].should be_within(1e-10).of 0.01280
|
277
|
+
prob_hash[10].should be_within(1e-10).of 0.02101
|
278
|
+
prob_hash[12].should be_within(1e-10).of 0.045715
|
279
|
+
prob_hash[13].should be_within(1e-10).of 0.060830
|
280
|
+
prob_hash[14].should be_within(1e-10).of 0.077915
|
281
|
+
prob_hash[15].should be_within(1e-10).of 0.090080
|
282
|
+
prob_hash[16].should be_within(1e-10).of 0.097935
|
283
|
+
prob_hash[17].should be_within(1e-10).of 0.091230
|
284
|
+
prob_hash[18].should be_within(1e-10).of 0.070015
|
285
|
+
prob_hash[19].should be_within(1e-10).of 0.020480
|
286
|
+
prob_hash[20].should be_within(1e-10).of 0.032805
|
287
|
+
prob_hash[22].should be_within(1e-10).of 0.0334626451
|
288
|
+
prob_hash[23].should be_within(1e-10).of 0.0338904805
|
289
|
+
prob_hash[24].should be_within(1e-10).of 0.0338098781
|
290
|
+
prob_hash[25].should be_within(1e-10).of 0.0328226480
|
291
|
+
prob_hash[26].should be_within(1e-10).of 0.0304393461
|
292
|
+
prob_hash[27].should be_within(1e-10).of 0.0260456005
|
293
|
+
prob_hash[28].should be_within(1e-10).of 0.0189361531
|
294
|
+
prob_hash[29].should be_within(1e-10).of 0.0082804480
|
295
|
+
prob_hash[30].should be_within(1e-10).of 0.0103524151
|
296
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
291
297
|
end
|
292
298
|
end
|
293
299
|
|
294
300
|
describe 'roll 2d20, keep best value' do
|
295
|
-
let(:
|
301
|
+
let(:bunch) do
|
296
302
|
GamesDice::Bunch.new(
|
297
303
|
:sides => 20, :ndice => 2, :keep_mode => :keep_best, :keep_number => 1
|
298
304
|
)
|
@@ -300,8 +306,8 @@ describe GamesDice::Bunch do
|
|
300
306
|
|
301
307
|
it "should simulate rolling two twenty-sided dice and keeping the best value" do
|
302
308
|
[19,18,14,6,13,10,16].each do |expected_total|
|
303
|
-
|
304
|
-
|
309
|
+
bunch.roll.should == expected_total
|
310
|
+
bunch.result.should == expected_total
|
305
311
|
end
|
306
312
|
end
|
307
313
|
|
@@ -311,47 +317,48 @@ describe GamesDice::Bunch do
|
|
311
317
|
"5, 14. Keep: 14",
|
312
318
|
"3, 6. Keep: 6",
|
313
319
|
].each do |expected_explain|
|
314
|
-
|
315
|
-
|
320
|
+
bunch.roll
|
321
|
+
bunch.explain_result.should == expected_explain
|
316
322
|
end
|
317
323
|
end
|
318
324
|
|
319
325
|
it "should calculate correct min, max = 1,20" do
|
320
|
-
|
321
|
-
|
326
|
+
bunch.min.should == 1
|
327
|
+
bunch.max.should == 20
|
322
328
|
end
|
323
329
|
|
324
330
|
it "should have a mean value of 13.825" do
|
325
|
-
|
331
|
+
bunch.probabilities.expected.should be_within(1e-9).of 13.825
|
326
332
|
end
|
327
333
|
|
328
334
|
it "should calculate probabilities correctly" do
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
335
|
+
prob_hash = bunch.probabilities.to_h
|
336
|
+
prob_hash[1].should be_within(1e-10).of 1/400.0
|
337
|
+
prob_hash[2].should be_within(1e-10).of 3/400.0
|
338
|
+
prob_hash[3].should be_within(1e-10).of 5/400.0
|
339
|
+
prob_hash[4].should be_within(1e-10).of 7/400.0
|
340
|
+
prob_hash[5].should be_within(1e-10).of 9/400.0
|
341
|
+
prob_hash[6].should be_within(1e-10).of 11/400.0
|
342
|
+
prob_hash[7].should be_within(1e-10).of 13/400.0
|
343
|
+
prob_hash[8].should be_within(1e-10).of 15/400.0
|
344
|
+
prob_hash[9].should be_within(1e-10).of 17/400.0
|
345
|
+
prob_hash[10].should be_within(1e-10).of 19/400.0
|
346
|
+
prob_hash[11].should be_within(1e-10).of 21/400.0
|
347
|
+
prob_hash[12].should be_within(1e-10).of 23/400.0
|
348
|
+
prob_hash[13].should be_within(1e-10).of 25/400.0
|
349
|
+
prob_hash[14].should be_within(1e-10).of 27/400.0
|
350
|
+
prob_hash[15].should be_within(1e-10).of 29/400.0
|
351
|
+
prob_hash[16].should be_within(1e-10).of 31/400.0
|
352
|
+
prob_hash[17].should be_within(1e-10).of 33/400.0
|
353
|
+
prob_hash[18].should be_within(1e-10).of 35/400.0
|
354
|
+
prob_hash[19].should be_within(1e-10).of 37/400.0
|
355
|
+
prob_hash[20].should be_within(1e-10).of 39/400.0
|
356
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
350
357
|
end
|
351
358
|
end
|
352
359
|
|
353
360
|
describe 'roll 2d20, keep worst value' do
|
354
|
-
let(:
|
361
|
+
let(:bunch) do
|
355
362
|
GamesDice::Bunch.new(
|
356
363
|
:sides => 20, :ndice => 2, :keep_mode => :keep_worst, :keep_number => 1
|
357
364
|
)
|
@@ -359,8 +366,8 @@ describe GamesDice::Bunch do
|
|
359
366
|
|
360
367
|
it "should simulate rolling two twenty-sided dice and keeping the best value" do
|
361
368
|
[14,16,5,3,7,5,9].each do |expected_total|
|
362
|
-
|
363
|
-
|
369
|
+
bunch.roll.should == expected_total
|
370
|
+
bunch.result.should == expected_total
|
364
371
|
end
|
365
372
|
end
|
366
373
|
|
@@ -370,42 +377,43 @@ describe GamesDice::Bunch do
|
|
370
377
|
"5, 14. Keep: 5",
|
371
378
|
"3, 6. Keep: 3",
|
372
379
|
].each do |expected_explain|
|
373
|
-
|
374
|
-
|
380
|
+
bunch.roll
|
381
|
+
bunch.explain_result.should == expected_explain
|
375
382
|
end
|
376
383
|
end
|
377
384
|
|
378
385
|
it "should calculate correct min, max = 1,20" do
|
379
|
-
|
380
|
-
|
386
|
+
bunch.min.should == 1
|
387
|
+
bunch.max.should == 20
|
381
388
|
end
|
382
389
|
|
383
390
|
it "should have a mean value of 7.175" do
|
384
|
-
|
391
|
+
bunch.probabilities.expected.should be_within(1e-9).of 7.175
|
385
392
|
end
|
386
393
|
|
387
394
|
it "should calculate probabilities correctly" do
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
395
|
+
prob_hash = bunch.probabilities.to_h
|
396
|
+
prob_hash[1].should be_within(1e-10).of 39/400.0
|
397
|
+
prob_hash[2].should be_within(1e-10).of 37/400.0
|
398
|
+
prob_hash[3].should be_within(1e-10).of 35/400.0
|
399
|
+
prob_hash[4].should be_within(1e-10).of 33/400.0
|
400
|
+
prob_hash[5].should be_within(1e-10).of 31/400.0
|
401
|
+
prob_hash[6].should be_within(1e-10).of 29/400.0
|
402
|
+
prob_hash[7].should be_within(1e-10).of 27/400.0
|
403
|
+
prob_hash[8].should be_within(1e-10).of 25/400.0
|
404
|
+
prob_hash[9].should be_within(1e-10).of 23/400.0
|
405
|
+
prob_hash[10].should be_within(1e-10).of 21/400.0
|
406
|
+
prob_hash[11].should be_within(1e-10).of 19/400.0
|
407
|
+
prob_hash[12].should be_within(1e-10).of 17/400.0
|
408
|
+
prob_hash[13].should be_within(1e-10).of 15/400.0
|
409
|
+
prob_hash[14].should be_within(1e-10).of 13/400.0
|
410
|
+
prob_hash[15].should be_within(1e-10).of 11/400.0
|
411
|
+
prob_hash[16].should be_within(1e-10).of 9/400.0
|
412
|
+
prob_hash[17].should be_within(1e-10).of 7/400.0
|
413
|
+
prob_hash[18].should be_within(1e-10).of 5/400.0
|
414
|
+
prob_hash[19].should be_within(1e-10).of 3/400.0
|
415
|
+
prob_hash[20].should be_within(1e-10).of 1/400.0
|
416
|
+
prob_hash.values.inject(:+).should be_within(1e-9).of 1.0
|
409
417
|
end
|
410
418
|
end
|
411
419
|
|