games_dice 0.1.1 → 0.1.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.
- 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
|