Class: Dicey::DistributionCalculators::BaseCalculator Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/dicey/distribution_calculators/base_calculator.rb

Overview

This class is abstract.

Base class for implementing distribution calculators.

Calculators have the following methods, each taking an array of dice:

By default, #call returns weights as they are easier to calculate and can be represented with integers (except for Empirical calculator). If probabilities are requested, they are calculated using Rational numbers to produce exact results.

An empty list of dice is considered a degenerate case, always valid for any calculator.

Options:

Calculators may have calculator-specific options, passed as extra keyword arguments to #call. If present, they will be documented under Options heading on the class itself.

Constant Summary collapse

RESULT_TYPES =

Possible values for result_type argument in #call.

i[weights probabilities].freeze

Instance Method Summary collapse

Instance Method Details

#call(dice, result_type: :weights, **options) ⇒ Hash{Any => Numeric}

Calculate distribution (probability mass function) for the list of dice.

Returns empty hash for an empty list of dice.

Parameters:

  • dice (Enumerable<AbstractDie>)
  • result_type (Symbol) (defaults to: :weights)

    one of RESULT_TYPES

  • options (Hash{Symbol => Any})

    calculator-specific options, refer to the calculator’s documentation to see what it accepts

Returns:

  • (Hash{Any => Numeric})

    weight or probability for each outcome, sorted by outcome if possible

Raises:

  • (DiceyError)

    if result_type is invalid

  • (DiceyError)

    if dice list is invalid for the calculator

  • (DiceyError)

    if calculator returned obviously wrong results (should not happen in released versions)



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/dicey/distribution_calculators/base_calculator.rb', line 46

def call(dice, result_type: :weights, **options)
  unless RESULT_TYPES.include?(result_type)
    raise DiceyError, "#{result_type} is not a valid result type!"
  end
  raise DiceyError, "#{self.class} can not handle these dice!" unless valid_for?(dice)

  # Short-circuit for a degenerate case.
  return {} if dice.empty?

  distribution = calculate(dice, **options)
  verify_result(distribution, dice)
  distribution = sort_result(distribution)
  transform_result(distribution, result_type)
end

#heuristic_complexity(dice) ⇒ Integer

Heuristic complexity of the calculator, used to determine best calculator.

Will always return a value, even if the calculator is not valid for the dice.

Parameters:

Returns:

  • (Integer)

    0 if dice is empty, otherwise can be any value

See Also:



77
78
79
80
81
# File 'lib/dicey/distribution_calculators/base_calculator.rb', line 77

def heuristic_complexity(dice)
  return 0 if dice.empty?

  calculate_heuristic(dice.length, dice.map(&:sides_num).max).to_i
end

#valid_for?(dice) ⇒ Boolean

Whether this calculator can be used for the list of dice.

Parameters:

Returns:

  • (Boolean)


65
66
67
# File 'lib/dicey/distribution_calculators/base_calculator.rb', line 65

def valid_for?(dice)
  dice.is_a?(Enumerable) && (dice.empty? || (dice.all?(AbstractDie) && validate(dice)))
end