Class: Dice_Stats::Dice

Inherits:
Object
  • Object
show all
Defined in:
lib/Dice.rb

Overview

This class repsents the roll statistics for a single type of dice. i.e. all d6s, or all d8s. The probability distribution is generated via the generating function found on line (10) of mathworld.wolfram.com/Dice.html

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dice_count, dice_sides, do_calculation = true) ⇒ Dice

Creates a new Dice instance of a number of dice (dice_count) with dice_sides faces. All dice are assumed to go from 1 to dice_sides.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/Dice.rb', line 22

def initialize(dice_count, dice_sides, do_calculation=true)
  @count = dice_count
  @sides = dice_sides
  @probability_distribution = {}

  if (@count < 0 || @sides < 0)
    #error
  else
    if do_calculation
      @probability_distribution = calculate_probability_distribution
    else
      @probability_distribution = {}
    end
  end
end

Instance Attribute Details

#countObject

The number of dice, and how many sides they have.



13
14
15
# File 'lib/Dice.rb', line 13

def count
  @count
end

#probability_distributionObject (readonly)

The probability distribution of the dice.



17
18
19
# File 'lib/Dice.rb', line 17

def probability_distribution
  @probability_distribution
end

#sidesObject

The number of dice, and how many sides they have.



13
14
15
# File 'lib/Dice.rb', line 13

def sides
  @sides
end

Instance Method Details

#calculate_probability_distributionObject

For internal use only. Caclulates the probability distribution on initialization



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/Dice.rb', line 100

def calculate_probability_distribution
  number_of_possible_combinations = (@sides**@count)
  #puts "Number of possible combinations: #{number_of_possible_combinations}"
  result = {}
  # weep softly: http://mathworld.wolfram.com/Dice.html
  (min..max).each { |p|
    if p > (max + min) / 2
      result[p] = result[max - p + min]
    else
      thing = (BigDecimal.new(p - @count) / BigDecimal.new(@sides)).floor

      c = BigDecimal.new(0)
      ((0..thing).each { |k|
        n1 = ((-1)**k) 
        n2 = BigDecimal.new(Internal_Utilities::Math_Utilities.Choose(@count, k))
        n3 = BigDecimal.new(Internal_Utilities::Math_Utilities.Choose(p - (@sides * k) - 1, @count - 1))            
        t = BigDecimal.new(n1 * n2 * n3)

        c += t
      })

      #result = result.abs

      result[p] = BigDecimal.new(c) / BigDecimal.new(number_of_possible_combinations)
    end

    #puts "\tProbability of #{p}: #{@probability_distribution[p].add(0, 5).to_s('F')}" 
  }
  @probability_distribution = result
  #puts "Sum of probability_distribution: " + (@probability_distribution.inject(BigDecimal.new(0)) {|total, (k,v)| BigDecimal.new(total + v) }).add(0, 5).to_s('F')
end

#expectedObject

Returns the average roll result



52
53
54
# File 'lib/Dice.rb', line 52

def expected
  BigDecimal(@count) * ((@sides + 1.0) / 2.0)
end

#maxObject

Returns the highest possible roll



40
41
42
# File 'lib/Dice.rb', line 40

def max
  @count*@sides
end

#minObject

Returns the lowest possible roll



46
47
48
# File 'lib/Dice.rb', line 46

def min
  @count
end

#p(val) ⇒ Object

Returns the probability of a specific result (val). Not to be confused with Dice_Set#p.



134
135
136
137
138
139
140
# File 'lib/Dice.rb', line 134

def p(val)
  if (@probability_distribution.key?(val))
    return @probability_distribution[val]
  else
    return 0
  end
end

Prints some basic stats about this roll



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/Dice.rb', line 75

def print_stats
  puts "Min: #{min}"
  puts "Max: #{max}"
  puts "Expected: #{expected}"
  puts "Std Dev: #{standard_deviation}"
  puts "Variance: #{variance}"

  @probability_distribution.each { |k,v| 
    puts "P(#{k}) => #{v}"
  }
end

#rollObject

Rolls the dice and returns the result



89
90
91
92
93
94
95
# File 'lib/Dice.rb', line 89

def roll
  sum = 0
  @count.times do |i|
    sum += (1 + rand(@sides))
  end
  return sum
end

#standard_deviationObject

Returns the standard deviation of the roll



69
70
71
# File 'lib/Dice.rb', line 69

def standard_deviation
  BigDecimal.new(variance).sqrt(5)
end

#varianceObject

Returns the variance of the roll



58
59
60
61
62
63
64
65
# File 'lib/Dice.rb', line 58

def variance
  var = BigDecimal.new(0)
  (1..@sides).each { |i|
    e = BigDecimal.new(@sides+1) / BigDecimal.new(2)
    var += (BigDecimal.new(i - e)**2) / BigDecimal.new(@sides)
  }
  var * BigDecimal.new(@count)
end