games_dice 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/{travis.yml → .travis.yml} +0 -0
- data/README.md +53 -6
- data/games_dice.gemspec +2 -1
- data/lib/games_dice/version.rb +1 -1
- data/spec/complex_die_spec.rb +0 -10
- data/spec/die_spec.rb +0 -11
- data/spec/helpers.rb +49 -0
- data/spec/probability_spec.rb +0 -39
- data/spec/readme_spec.rb +62 -10
- metadata +8 -5
data/{travis.yml → .travis.yml}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -114,31 +114,78 @@ Convenience method, returns an array [ dice.min, dice.max ]
|
|
114
114
|
|
115
115
|
#### dice.probabilities
|
116
116
|
|
117
|
-
Calculates probability distribution for the dice.
|
118
|
-
a number best or worst results, can take significant time to calculate.
|
117
|
+
Calculates probability distribution for the dice.
|
119
118
|
|
120
119
|
Returns a GamesDice::Probabilities object that describes the probability distribution.
|
121
120
|
|
122
121
|
probabilities = dice.probabilities
|
123
122
|
|
123
|
+
Note that some distributions, involving keeping a number best or worst results, can take
|
124
|
+
significant time to calculate. If the theoretical distribution would contain a large number
|
125
|
+
of very low probabilities due to a possibility of large numbers re-rolls, then the
|
126
|
+
calculations cut short, typically approximating to the nearest 1.0e-10.
|
127
|
+
|
124
128
|
### GamesDice::Probabilities instance methods
|
125
129
|
|
126
130
|
#### probabilities.to_h
|
127
131
|
|
128
|
-
Returns a hash representation of the probability distribution. Each
|
132
|
+
Returns a hash representation of the probability distribution. Each key is a possible result
|
129
133
|
from rolling the dice (an Integer), and the associated value is the probability of a roll
|
130
|
-
returning that
|
134
|
+
returning that result (a Float, between 0.0 and 1.0 inclusive).
|
135
|
+
|
136
|
+
distribution = probabilities.to_h
|
137
|
+
distribution[3] # => 0.0046296296296
|
131
138
|
|
132
139
|
#### probabilities.max
|
133
140
|
|
134
|
-
Returns maximum
|
141
|
+
Returns maximum result in the probability distribution. This may not be the theoretical maximum
|
135
142
|
possible on the dice, if for example the dice can roll open-ended high results.
|
136
143
|
|
144
|
+
probabilities.max # => 18
|
145
|
+
|
137
146
|
#### probabilities.min
|
138
147
|
|
139
|
-
Returns minimum
|
148
|
+
Returns minimum result in the probability distribution. This may not be the theoretical minimum
|
140
149
|
possible on the dice, if for example the dice can roll open-ended low results.
|
141
150
|
|
151
|
+
probabilities.min # => 3
|
152
|
+
|
153
|
+
#### probabilities.p_eql( n )
|
154
|
+
|
155
|
+
Returns the probability of a result equal to the integer n.
|
156
|
+
|
157
|
+
probabilities.p_eql( 3 ) # => 0.004629629629
|
158
|
+
probabilities.p_eql( 2 ) # => 0.0
|
159
|
+
|
160
|
+
Probabilities below 1e-10 due to requiring long sequences of re-rolls will calculate as 0.0
|
161
|
+
|
162
|
+
#### probabilities.p_gt( n )
|
163
|
+
|
164
|
+
Returns the probability of a result greater than the integer n.
|
165
|
+
|
166
|
+
probabilities.p_gt( 17 ) # => 0.004629629629
|
167
|
+
probabilities.p_gt( 2 ) # => 1.0
|
168
|
+
|
169
|
+
#### probabilities.p_ge( n )
|
170
|
+
|
171
|
+
Returns the probability of a result greater than or equal to the integer n.
|
172
|
+
|
173
|
+
probabilities.p_ge( 17 ) # => 0.0185185185185
|
174
|
+
probabilities.p_ge( 3 ) # => 1.0
|
175
|
+
|
176
|
+
#### probabilities.p_le( n )
|
177
|
+
|
178
|
+
Returns the probability of a result less than or equal to the integer n.
|
179
|
+
|
180
|
+
probabilities.p_le( 17 ) # => 0.9953703703703
|
181
|
+
probabilities.p_le( 3 ) # => 0.0046296296296
|
182
|
+
|
183
|
+
#### probabilities.p_lt( n )
|
184
|
+
|
185
|
+
Returns the probability of a result less than the integer n.
|
186
|
+
|
187
|
+
probabilities.p_lt( 17 ) # => 0.9953703703703
|
188
|
+
probabilities.p_lt( 3 ) # => 0.0
|
142
189
|
|
143
190
|
## String Dice Descriptions
|
144
191
|
|
data/games_dice.gemspec
CHANGED
@@ -10,7 +10,8 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ["slobo777@gmail.com"]
|
11
11
|
gem.description = %q{A simulated-dice library, with flexible rules that allow dice systems from
|
12
12
|
many board and roleplay games to be built, run and reported.}
|
13
|
-
gem.summary = %q{Simulates and explains dice rolls from
|
13
|
+
gem.summary = %q{Simulates and explains dice rolls from simple "1d6" to complex "roll 7 ten-sided dice, take best 3,
|
14
|
+
results of 10 roll again and add on".}
|
14
15
|
gem.homepage = "https://github.com/neilslater/games_dice"
|
15
16
|
|
16
17
|
gem.add_development_dependency "rspec", ">= 2.13.0"
|
data/lib/games_dice/version.rb
CHANGED
data/spec/complex_die_spec.rb
CHANGED
@@ -1,15 +1,5 @@
|
|
1
1
|
require 'games_dice'
|
2
2
|
|
3
|
-
# Test helper class, a stub of a PRNG
|
4
|
-
class TestPRNG
|
5
|
-
def initialize
|
6
|
-
@numbers = [0.123,0.234,0.345,0.999,0.876,0.765,0.543,0.111,0.333,0.777]
|
7
|
-
end
|
8
|
-
def rand(n)
|
9
|
-
Integer( n * @numbers.pop )
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
3
|
describe GamesDice::ComplexDie do
|
14
4
|
|
15
5
|
before do
|
data/spec/die_spec.rb
CHANGED
@@ -1,16 +1,5 @@
|
|
1
1
|
require 'games_dice'
|
2
2
|
|
3
|
-
# Test helper class, a stub of a PRNG
|
4
|
-
class TestPRNG
|
5
|
-
def initialize
|
6
|
-
# Numbers that I randomly thought up!
|
7
|
-
@numbers = [0.123,0.234,0.345,0.999,0.876,0.765,0.543,0.111,0.333,0.777]
|
8
|
-
end
|
9
|
-
def rand(n)
|
10
|
-
Integer( n * @numbers.pop )
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
3
|
describe GamesDice::Die do
|
15
4
|
|
16
5
|
before do
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# games_dice/spec/helpers.rb
|
2
|
+
|
3
|
+
class TestPRNG
|
4
|
+
def initialize
|
5
|
+
@numbers = [0.123,0.234,0.345,0.999,0.876,0.765,0.543,0.111,0.333,0.777]
|
6
|
+
end
|
7
|
+
def rand(n)
|
8
|
+
Integer( n * @numbers.pop )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# A valid distribution is:
|
13
|
+
# A hash
|
14
|
+
# Keys are all Integers
|
15
|
+
# Values are all positive Floats, between 0.0 and 1.0
|
16
|
+
# Sum of values is 1.0
|
17
|
+
RSpec::Matchers.define :be_valid_distribution do
|
18
|
+
match do |given|
|
19
|
+
@error = nil
|
20
|
+
if ! given.is_a?(Hash)
|
21
|
+
@error = "distribution should be a Hash, but it is a #{given.class}"
|
22
|
+
elsif given.keys.any? { |k| ! k.is_a?(Fixnum) }
|
23
|
+
bad_key = given.keys.first { |k| ! k.is_a?(Fixnum) }
|
24
|
+
@error = "all keys should be Fixnums, but found '#{bad_key.inspect}' which is a #{bad_key.class}"
|
25
|
+
elsif given.values.any? { |v| ! v.is_a?(Float) }
|
26
|
+
bad_value = given.values.first { |v| ! v.is_a?(Float) }
|
27
|
+
@error = "all values should be Floats, but found '#{bad_value.inspect}' which is a #{bad_value.class}"
|
28
|
+
elsif given.values.any? { |v| v < 0.0 || v > 1.0 }
|
29
|
+
bad_value = given.values.first { |v| v < 0.0 || v > 1.0 }
|
30
|
+
@error = "all values should be in range (0.0..1.0), but found #{bad_value}"
|
31
|
+
elsif (1.0 - given.values.inject(:+)).abs > 1e-6
|
32
|
+
total_probs = given.values.inject(:+)
|
33
|
+
@error = "sum of values should be 1.0, but got #{total_probs}"
|
34
|
+
end
|
35
|
+
! @error
|
36
|
+
end
|
37
|
+
|
38
|
+
failure_message_for_should do |given|
|
39
|
+
@error ? @error : 'Distribution is valid and complete'
|
40
|
+
end
|
41
|
+
|
42
|
+
failure_message_for_should_not do |given|
|
43
|
+
@error ? @error : 'Distribution is valid and complete'
|
44
|
+
end
|
45
|
+
|
46
|
+
description do |given|
|
47
|
+
"a hash describing a complete probability distribution of integer results"
|
48
|
+
end
|
49
|
+
end
|
data/spec/probability_spec.rb
CHANGED
@@ -1,44 +1,5 @@
|
|
1
1
|
require 'games_dice'
|
2
2
|
|
3
|
-
# A valid distribution is:
|
4
|
-
# A hash
|
5
|
-
# Keys are all Integers
|
6
|
-
# Values are all positive Floats, between 0.0 and 1.0
|
7
|
-
# Sum of values is 1.0
|
8
|
-
RSpec::Matchers.define :be_valid_distribution do
|
9
|
-
match do |given|
|
10
|
-
@error = nil
|
11
|
-
if ! given.is_a?(Hash)
|
12
|
-
@error = "distribution should be a Hash, but it is a #{given.class}"
|
13
|
-
elsif given.keys.any? { |k| ! k.is_a?(Fixnum) }
|
14
|
-
bad_key = given.keys.first { |k| ! k.is_a?(Fixnum) }
|
15
|
-
@error = "all keys should be Fixnums, but found '#{bad_key.inspect}' which is a #{bad_key.class}"
|
16
|
-
elsif given.values.any? { |v| ! v.is_a?(Float) }
|
17
|
-
bad_value = given.values.first { |v| ! v.is_a?(Float) }
|
18
|
-
@error = "all values should be Floats, but found '#{bad_value.inspect}' which is a #{bad_value.class}"
|
19
|
-
elsif given.values.any? { |v| v < 0.0 || v > 1.0 }
|
20
|
-
bad_value = given.values.first { |v| v < 0.0 || v > 1.0 }
|
21
|
-
@error = "all values should be in range (0.0..1.0), but found #{bad_value}"
|
22
|
-
elsif (1.0 - given.values.inject(:+)).abs > 1e-6
|
23
|
-
total_probs = given.values.inject(:+)
|
24
|
-
@error = "sum of values should be 1.0, but got #{total_probs}"
|
25
|
-
end
|
26
|
-
! @error
|
27
|
-
end
|
28
|
-
|
29
|
-
failure_message_for_should do |given|
|
30
|
-
@error ? @error : 'Distribution is valid and complete'
|
31
|
-
end
|
32
|
-
|
33
|
-
failure_message_for_should_not do |given|
|
34
|
-
@error ? @error : 'Distribution is valid and complete'
|
35
|
-
end
|
36
|
-
|
37
|
-
description do |given|
|
38
|
-
"a hash describing a complete probability distribution of integer results"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
3
|
describe GamesDice::Probabilities do
|
43
4
|
|
44
5
|
describe "class methods" do
|
data/spec/readme_spec.rb
CHANGED
@@ -1,16 +1,7 @@
|
|
1
1
|
require 'games_dice'
|
2
|
+
require 'helpers'
|
2
3
|
# This spec demonstrates that documentation from the README.md works as intended
|
3
4
|
|
4
|
-
# Test helper class, a stub of a PRNG
|
5
|
-
class TestPRNG
|
6
|
-
def initialize
|
7
|
-
@numbers = [0.123,0.234,0.345,0.999,0.876,0.765,0.543,0.111,0.333,0.777]
|
8
|
-
end
|
9
|
-
def rand(n)
|
10
|
-
Integer( n * @numbers.pop )
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
5
|
describe GamesDice do
|
15
6
|
|
16
7
|
describe '#create' do
|
@@ -94,3 +85,64 @@ describe GamesDice::Dice do
|
|
94
85
|
end
|
95
86
|
|
96
87
|
end # describe GamesDice::Dice
|
88
|
+
|
89
|
+
describe GamesDice::Probabilities do
|
90
|
+
let(:probs) { GamesDice.create('3d6').probabilities }
|
91
|
+
|
92
|
+
describe "#to_h" do
|
93
|
+
it "returns a hash representation of the probability distribution" do
|
94
|
+
h = probs.to_h
|
95
|
+
h.should be_valid_distribution
|
96
|
+
h[3].should be_within(1e-10).of 1.0/216
|
97
|
+
h[11].should be_within(1e-10).of 27.0/216
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#max" do
|
102
|
+
it "returns maximum result in the probability distribution" do
|
103
|
+
probs.max.should == 18
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#min" do
|
108
|
+
it "returns minimum result in the probability distribution" do
|
109
|
+
probs.min.should == 3
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#p_eql( n )" do
|
114
|
+
it "returns the probability of a result equal to the integer n" do
|
115
|
+
probs.p_eql( 3 ).should be_within(1e-10).of 1.0/216
|
116
|
+
probs.p_eql( 2 ).should == 0.0
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#p_gt( n )" do
|
121
|
+
it "returns the probability of a result greater than the integer n" do
|
122
|
+
probs.p_gt( 17 ).should be_within(1e-10).of 1.0/216
|
123
|
+
probs.p_gt( 2 ).should == 1.0
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#p_ge( n )" do
|
128
|
+
it "returns the probability of a result greater than the integer n" do
|
129
|
+
probs.p_ge( 17 ).should be_within(1e-10).of 4.0/216
|
130
|
+
probs.p_ge( 3 ).should == 1.0
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#p_le( n )" do
|
135
|
+
it "returns the probability of a result less than or equal to the integer n" do
|
136
|
+
probs.p_le( 17 ).should be_within(1e-10).of 215.0/216
|
137
|
+
probs.p_le( 3 ).should be_within(1e-10).of 1.0/216
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#p_lt( n )" do
|
142
|
+
it "returns the probability of a result less than the integer n" do
|
143
|
+
probs.p_lt( 17 ).should be_within(1e-10).of 212.0/216
|
144
|
+
probs.p_lt( 3 ).should == 0.0
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end # describe GamesDice::Probabilities
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: games_dice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -69,6 +69,7 @@ extensions: []
|
|
69
69
|
extra_rdoc_files: []
|
70
70
|
files:
|
71
71
|
- .gitignore
|
72
|
+
- .travis.yml
|
72
73
|
- Gemfile
|
73
74
|
- LICENSE.txt
|
74
75
|
- README.md
|
@@ -91,12 +92,12 @@ files:
|
|
91
92
|
- spec/dice_spec.rb
|
92
93
|
- spec/die_result_spec.rb
|
93
94
|
- spec/die_spec.rb
|
95
|
+
- spec/helpers.rb
|
94
96
|
- spec/map_rule_spec.rb
|
95
97
|
- spec/parser_spec.rb
|
96
98
|
- spec/probability_spec.rb
|
97
99
|
- spec/readme_spec.rb
|
98
100
|
- spec/reroll_rule_spec.rb
|
99
|
-
- travis.yml
|
100
101
|
homepage: https://github.com/neilslater/games_dice
|
101
102
|
licenses: []
|
102
103
|
post_install_message:
|
@@ -111,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
112
|
version: '0'
|
112
113
|
segments:
|
113
114
|
- 0
|
114
|
-
hash:
|
115
|
+
hash: -2496597161129373974
|
115
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
117
|
none: false
|
117
118
|
requirements:
|
@@ -120,19 +121,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
121
|
version: '0'
|
121
122
|
segments:
|
122
123
|
- 0
|
123
|
-
hash:
|
124
|
+
hash: -2496597161129373974
|
124
125
|
requirements: []
|
125
126
|
rubyforge_project:
|
126
127
|
rubygems_version: 1.8.24
|
127
128
|
signing_key:
|
128
129
|
specification_version: 3
|
129
|
-
summary: Simulates and explains dice rolls from
|
130
|
+
summary: Simulates and explains dice rolls from simple "1d6" to complex "roll 7 ten-sided
|
131
|
+
dice, take best 3, results of 10 roll again and add on".
|
130
132
|
test_files:
|
131
133
|
- spec/bunch_spec.rb
|
132
134
|
- spec/complex_die_spec.rb
|
133
135
|
- spec/dice_spec.rb
|
134
136
|
- spec/die_result_spec.rb
|
135
137
|
- spec/die_spec.rb
|
138
|
+
- spec/helpers.rb
|
136
139
|
- spec/map_rule_spec.rb
|
137
140
|
- spec/parser_spec.rb
|
138
141
|
- spec/probability_spec.rb
|