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.
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. Note that some distributions, involving keeping
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 keys is a possible result
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 value (a Float).
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 value in the probability distribution. This may not be the theoretical 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 value in the probability distribution. This may not be the theoretical 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 a variety of game systems.}
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"
@@ -1,3 +1,3 @@
1
1
  module GamesDice
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -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
@@ -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.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: 514639472622102988
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: 514639472622102988
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 a variety of game systems.
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