# Class: GamesDice::Probabilities

Inherits:
Object
• Object
show all
Defined in:
lib/games_dice/probabilities.rb,
lib/games_dice/marshal.rb

## Overview

This class models probability distributions for dice systems.

An object of this class represents a single distribution, which might be the result of a complex combination of dice.

Examples:

Distribution for a six-sided die

``````probs = GamesDice::Probabilities.for_fair_die( 6 )
probs.min # => 1
probs.max # => 6
probs.expected # => 3.5
probs.p_ge( 4 ) # => 0.5``````

``````pd6 = GamesDice::Probabilities.for_fair_die( 6 )
probs = GamesDice::Probabilities.add_distributions( pd6, pd6 )
probs.min # => 2
probs.max # => 12
probs.expected # => 7.0
probs.p_ge( 10 ) # => 0.16666666666666669``````

## Instance Attribute Summary collapse

Expected value of distribution.

Maximum result in the distribution.

Minimum result in the distribution.

## Class Method Summary collapse

• Combines two distributions to create a third, that represents the distribution created when adding results together.

• Combines two distributions with multipliers to create a third, that represents the distribution created when adding weighted results together.

• Distribution for a die with equal chance of rolling 1..N.

• Creates new instance of GamesDice::Probabilities.

• Returns a symbol for the language name that this class is implemented in.

## Instance Method Summary collapse

• Iterates through value, probability pairs.

• Probability distribution derived from this one, where we know (or are only interested in situations where) the result is greater than or equal to target.

• Probability distribution derived from this one, where we know (or are only interested in situations where) the result is less than or equal to target.

• constructor

Creates new instance of GamesDice::Probabilities.

• Probability of result equalling specific target.

• Probability of result being equal to or greater than specific target.

• Probability of result being greater than specific target.

• Probability of result being equal to or less than specific target.

• Probability of result being less than specific target.

• Calculates distribution generated by summing best k results of n iterations of the distribution.

• Adds a distribution to itself repeatedly, to simulate a number of dice results being summed.

• A hash representation of the distribution.

## Constructor Details

### #initialize(probs = [1.0], offset = 0) ⇒ GamesDice::Probabilities

Creates new instance of GamesDice::Probabilities.

Parameters:

• probs (Array<Float>) (defaults to: [1.0])

Each entry in the array is the probability of getting a result

• offset (Integer) (defaults to: 0)

The result associated with index of 0 in the array

 ``` 32 33 34 35 36``` ```# File 'lib/games_dice/probabilities.rb', line 32 def initialize( probs = [1.0], offset = 0 ) # This should *probably* be validated in future, but that would impact performance @probs = check_probs_array probs.clone @offset = Integer(offset) end```

## Instance Attribute Details

Expected value of distribution.

Returns:

• (Float)
 ``` 72 73 74``` ```# File 'lib/games_dice/probabilities.rb', line 72 def expected @expected ||= calc_expected end```

Maximum result in the distribution

Returns:

• (Integer)
 ``` 65 66 67``` ```# File 'lib/games_dice/probabilities.rb', line 65 def max @offset + @probs.count() - 1 end```

Minimum result in the distribution

Returns:

• (Integer)
 ``` 58 59 60``` ```# File 'lib/games_dice/probabilities.rb', line 58 def min @offset end```

## Class Method Details

Combines two distributions to create a third, that represents the distribution created when adding results together.

Parameters:

• pd_a

First distribution

• pd_b

Second distribution

Returns:

 ``` 178 179 180 181 182 183 184``` ```# File 'lib/games_dice/probabilities.rb', line 178 def self.add_distributions pd_a, pd_b check_is_gdp( pd_a, pd_b ) combined_min = pd_a.min + pd_b.min combined_max = pd_a.max + pd_b.max add_distributions_internal( combined_min, combined_max, 1, pd_a, 1, pd_b ) end```

### .add_distributions_mult(m_a, pd_a, m_b, pd_b) ⇒ GamesDice::Probabilities

Combines two distributions with multipliers to create a third, that represents the distribution created when adding weighted results together.

Parameters:

• m_a (Integer)

Weighting for first distribution

• pd_a

First distribution

• m_b (Integer)

Weighting for second distribution

• pd_b

Second distribution

Returns:

 ``` 193 194 195 196 197 198 199 200 201``` ```# File 'lib/games_dice/probabilities.rb', line 193 def self.add_distributions_mult m_a, pd_a, m_b, pd_b check_is_gdp( pd_a, pd_b ) m_a = Integer(m_a) m_b = Integer(m_b) combined_min, combined_max = calc_combined_extremes( m_a, pd_a, m_b, pd_b ).minmax add_distributions_internal( combined_min, combined_max, m_a, pd_a, m_b, pd_b ) end```

### .for_fair_die(sides) ⇒ GamesDice::Probabilities

Distribution for a die with equal chance of rolling 1..N

Parameters:

• sides (Integer)

Number of sides on die

Returns:

Raises:

• (ArgumentError)
 ``` 166 167 168 169 170 171``` ```# File 'lib/games_dice/probabilities.rb', line 166 def self.for_fair_die sides sides = Integer(sides) raise ArgumentError, "sides must be at least 1" unless sides > 0 raise ArgumentError, "sides can be at most 100000" if sides > 100000 GamesDice::Probabilities.new( Array.new( sides, 1.0/sides ), 1 ) end```

### .from_h(prob_hash) ⇒ GamesDice::Probabilities

Creates new instance of GamesDice::Probabilities.

Parameters:

• prob_hash (Hash)

A hash representation of the distribution, each key is an integer result, and the matching value is probability of getting that result

Returns:

Raises:

• (TypeError)
 ``` 157 158 159 160 161``` ```# File 'lib/games_dice/probabilities.rb', line 157 def self.from_h prob_hash raise TypeError, "from_h expected a Hash" unless prob_hash.is_a? Hash probs, offset = prob_h_to_ao( prob_hash ) GamesDice::Probabilities.new( probs, offset ) end```

### .implemented_in ⇒ Symbol

Returns a symbol for the language name that this class is implemented in. The C version of the code is noticeably faster when dealing with larger numbers of possible results.

Returns:

• (Symbol)

Either :c or :ruby

 ``` 206 207 208``` ```# File 'lib/games_dice/probabilities.rb', line 206 def self.implemented_in :ruby end```

## Instance Method Details

### #each {|result, probability| ... } ⇒ GamesDice::Probabilities

Iterates through value, probability pairs

Yield Parameters:

• result (Integer)

A result that may be possible in the dice scheme

• probability (Float)

Probability of result, in range 0.0..1.0

Returns:

• this object

 ``` 42 43 44 45``` ```# File 'lib/games_dice/probabilities.rb', line 42 def each @probs.each_with_index { |p,i| yield( i+@offset, p ) if p > 0.0 } return self end```

### #given_ge(target) ⇒ GamesDice::Probabilities

Probability distribution derived from this one, where we know (or are only interested in situations where) the result is greater than or equal to target.

Parameters:

• target (Integer)

Returns:

• new distribution.

 ``` 129 130 131 132 133 134 135 136 137``` ```# File 'lib/games_dice/probabilities.rb', line 129 def given_ge target target = Integer(target) target = min if min > target p = p_ge(target) raise "There is no valid distribution given a result >= #{target}" unless p > 0.0 mult = 1.0/p new_probs = @probs[target-@offset,@probs.count-1].map { |x| x * mult } GamesDice::Probabilities.new( new_probs, target ) end```

### #given_le(target) ⇒ GamesDice::Probabilities

Probability distribution derived from this one, where we know (or are only interested in situations where) the result is less than or equal to target.

Parameters:

• target (Integer)

Returns:

• new distribution.

 ``` 143 144 145 146 147 148 149 150 151``` ```# File 'lib/games_dice/probabilities.rb', line 143 def given_le target target = Integer(target) target = max if max < target p = p_le(target) raise "There is no valid distribution given a result <= #{target}" unless p > 0.0 mult = 1.0/p new_probs = @probs[0..target-@offset].map { |x| x * mult } GamesDice::Probabilities.new( new_probs, @offset ) end```

### #p_eql(target) ⇒ Float

Probability of result equalling specific target

Parameters:

• target (Integer)

Returns:

• (Float)

in range (0.0..1.0)

 ``` 79 80 81 82 83``` ```# File 'lib/games_dice/probabilities.rb', line 79 def p_eql target i = Integer(target) - @offset return 0.0 if i < 0 || i >= @probs.count @probs[ i ] end```

### #p_ge(target) ⇒ Float

Probability of result being equal to or greater than specific target

Parameters:

• target (Integer)

Returns:

• (Float)

in range (0.0..1.0)

 ``` 95 96 97 98 99 100 101 102 103``` ```# File 'lib/games_dice/probabilities.rb', line 95 def p_ge target target = Integer(target) return @prob_ge[target] if @prob_ge && @prob_ge[target] @prob_ge = {} unless @prob_ge return 1.0 if target <= min return 0.0 if target > max @prob_ge[target] = @probs[target-@offset,@probs.count-1].inject(0.0) {|so_far,p| so_far + p } end```

### #p_gt(target) ⇒ Float

Probability of result being greater than specific target

Parameters:

• target (Integer)

Returns:

• (Float)

in range (0.0..1.0)

 ``` 88 89 90``` ```# File 'lib/games_dice/probabilities.rb', line 88 def p_gt target p_ge( Integer(target) + 1 ) end```

### #p_le(target) ⇒ Float

Probability of result being equal to or less than specific target

Parameters:

• target (Integer)

Returns:

• (Float)

in range (0.0..1.0)

 ``` 108 109 110 111 112 113 114 115 116``` ```# File 'lib/games_dice/probabilities.rb', line 108 def p_le target target = Integer(target) return @prob_le[target] if @prob_le && @prob_le[target] @prob_le = {} unless @prob_le return 1.0 if target >= max return 0.0 if target < min @prob_le[target] = @probs[0,1+target-@offset].inject(0.0) {|so_far,p| so_far + p } end```

### #p_lt(target) ⇒ Float

Probability of result being less than specific target

Parameters:

• target (Integer)

Returns:

• (Float)

in range (0.0..1.0)

 ``` 121 122 123``` ```# File 'lib/games_dice/probabilities.rb', line 121 def p_lt target p_le( Integer(target) - 1 ) end```

### #repeat_n_sum_k(n, k, kmode = :keep_best) ⇒ GamesDice::Probabilities

Calculates distribution generated by summing best k results of n iterations of the distribution.

Parameters:

• n (Integer)

Number of repetitions, must be at least 1

• k (Integer)

Number of best results to keep and sum

Returns:

• new distribution

 ``` 226 227 228 229 230 231 232 233 234``` ```# File 'lib/games_dice/probabilities.rb', line 226 def repeat_n_sum_k n, k, kmode = :keep_best n = Integer( n ) k = Integer( k ) raise "Cannot combine probabilities less than once" if n < 1 # Technically this is a limitation of C code, but Ruby version is most likely slow and inaccurate beyond 170 raise "Too many dice to calculate numbers of arrangements" if n > 170 check_keep_mode( kmode ) repeat_n_sum_k_internal( n, k, kmode ) end```

### #repeat_sum(n) ⇒ GamesDice::Probabilities

Adds a distribution to itself repeatedly, to simulate a number of dice results being summed.

Parameters:

• n (Integer)

Number of repetitions, must be at least 1

Returns:

• new distribution

 ``` 214 215 216 217 218 219``` ```# File 'lib/games_dice/probabilities.rb', line 214 def repeat_sum n n = Integer( n ) raise "Cannot combine probabilities less than once" if n < 1 raise "Probability distribution too large" if ( n * @probs.count ) > 1000000 repeat_sum_internal( n ) end```

### #to_h ⇒ Hash

A hash representation of the distribution. Each key is an integer result, and the matching value is probability of getting that result. A new hash is generated on each call to this method.

Returns:

• (Hash)
 ``` 51 52 53``` ```# File 'lib/games_dice/probabilities.rb', line 51 def to_h GamesDice::Probabilities.prob_ao_to_h( @probs, @offset ) end```