lib/games_dice/probabilities.rb in games_dice-0.3.3 vs lib/games_dice/probabilities.rb in games_dice-0.3.5

- old
+ new

@@ -24,11 +24,11 @@ # @param [Array<Float>] probs Each entry in the array is the probability of getting a result # @param [Integer] offset The result associated with index of 0 in the array # @return [GamesDice::Probabilities] def initialize( probs = [1.0], offset = 0 ) # This should *probably* be validated in future, but that would impact performance - @probs = probs + @probs = check_probs_array probs.clone @offset = offset end # @!visibility private # the Array, Offset representation of probabilities. @@ -216,10 +216,17 @@ end end GamesDice::Probabilities.new( new_probs, combined_min ) end + # 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. + # @return [Symbol] Either :c or :ruby + def self.implemented_in + :ruby + end + # Adds a distribution to itself repeatedly, to simulate a number of dice # results being summed. # @param [Integer] n Number of repetitions, must be at least 1 # @return [GamesDice::Probabilities] new distribution def repeat_sum n @@ -283,9 +290,23 @@ end GamesDice::Probabilities.new( new_probs, new_offset ) end private + + def check_probs_array probs_array + probs_array.map!{ |n| Float(n) } + total = probs_array.inject(0.0) do |t,x| + if x < 0.0 || x > 1.0 + raise ArgumentError, "Found probability value #{x} which is not in range 0.0..1.0" + end + t+x + end + if (total-1.0).abs > 1e-6 + raise ArgumentError, "Total probabilities too far from 1.0 for a valid distribution" + end + probs_array + end def calc_keep_distributions k, q, kmode if kmode == :keep_best keep_distributions = [ GamesDice::Probabilities.new( [1.0], q * k ) ] if p_gt(q) > 0.0 && k > 1