dicey 0.16.2 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +60 -37
- data/exe/dicey +2 -2
- data/lib/dicey/abstract_die.rb +24 -5
- data/lib/dicey/cli/blender.rb +19 -14
- data/lib/dicey/{sum_frequency_calculators/runner.rb → cli/calculator_runner.rb} +9 -15
- data/lib/dicey/{sum_frequency_calculators/test_runner.rb → cli/calculator_test_runner.rb} +37 -13
- data/lib/dicey/cli/formatters/base_list_formatter.rb +36 -0
- data/lib/dicey/cli/formatters/base_map_formatter.rb +38 -0
- data/lib/dicey/cli/formatters/gnuplot_formatter.rb +28 -0
- data/lib/dicey/cli/formatters/json_formatter.rb +14 -0
- data/lib/dicey/cli/formatters/list_formatter.rb +14 -0
- data/lib/dicey/cli/formatters/null_formatter.rb +17 -0
- data/lib/dicey/cli/formatters/yaml_formatter.rb +14 -0
- data/lib/dicey/cli/options.rb +15 -11
- data/lib/dicey/cli/roller.rb +47 -0
- data/lib/dicey/cli.rb +23 -0
- data/lib/dicey/die_foundry.rb +6 -5
- data/lib/dicey/distribution_calculators/auto_selector.rb +73 -0
- data/lib/dicey/{sum_frequency_calculators → distribution_calculators}/base_calculator.rb +44 -37
- data/lib/dicey/distribution_calculators/binomial.rb +62 -0
- data/lib/dicey/{sum_frequency_calculators → distribution_calculators}/empirical.rb +9 -10
- data/lib/dicey/distribution_calculators/iterative.rb +51 -0
- data/lib/dicey/{sum_frequency_calculators → distribution_calculators}/multinomial_coefficients.rb +21 -12
- data/lib/dicey/{sum_frequency_calculators/kronecker_substitution.rb → distribution_calculators/polynomial_convolution.rb} +15 -8
- data/lib/dicey/distribution_calculators/trivial.rb +56 -0
- data/lib/dicey/distribution_properties_calculator.rb +5 -2
- data/lib/dicey/mixins/missing_math.rb +44 -0
- data/lib/dicey/mixins/rational_to_integer.rb +1 -0
- data/lib/dicey/mixins/vectorize_dice.rb +17 -12
- data/lib/dicey/mixins/warn_about_vector_number.rb +19 -0
- data/lib/dicey/numeric_die.rb +1 -1
- data/lib/dicey/version.rb +1 -1
- data/lib/dicey.rb +26 -5
- metadata +30 -26
- data/lib/dicey/output_formatters/gnuplot_formatter.rb +0 -24
- data/lib/dicey/output_formatters/hash_formatter.rb +0 -36
- data/lib/dicey/output_formatters/json_formatter.rb +0 -12
- data/lib/dicey/output_formatters/key_value_formatter.rb +0 -34
- data/lib/dicey/output_formatters/list_formatter.rb +0 -12
- data/lib/dicey/output_formatters/null_formatter.rb +0 -15
- data/lib/dicey/output_formatters/yaml_formatter.rb +0 -12
- data/lib/dicey/roller.rb +0 -46
- data/lib/dicey/sum_frequency_calculators/auto_selector.rb +0 -41
- data/lib/dicey/sum_frequency_calculators/brute_force.rb +0 -41
data/lib/dicey/roller.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "die_foundry"
|
|
4
|
-
|
|
5
|
-
require_relative "mixins/rational_to_integer"
|
|
6
|
-
require_relative "mixins/vectorize_dice"
|
|
7
|
-
|
|
8
|
-
module Dicey
|
|
9
|
-
# Let the dice roll!
|
|
10
|
-
#
|
|
11
|
-
# This is the implementation of roll mode for the CLI.
|
|
12
|
-
class Roller
|
|
13
|
-
include Mixins::RationalToInteger
|
|
14
|
-
include Mixins::VectorizeDice
|
|
15
|
-
|
|
16
|
-
# @param arguments [Array<String>] die definitions
|
|
17
|
-
# @param format [#call] formatter for output
|
|
18
|
-
# @return [nil]
|
|
19
|
-
# @raise [DiceyError]
|
|
20
|
-
def call(arguments, format:, **)
|
|
21
|
-
raise DiceyError, "no dice!" if arguments.empty?
|
|
22
|
-
|
|
23
|
-
dice = arguments.flat_map { |definition| die_foundry.cast(definition) }
|
|
24
|
-
result = roll_dice(dice)
|
|
25
|
-
|
|
26
|
-
format.call({ "roll" => rational_to_integer(result) }, AbstractDie.describe(dice))
|
|
27
|
-
rescue TypeError
|
|
28
|
-
warn <<~TEXT
|
|
29
|
-
Dice with non-numeric sides need gem "vector_number" to be present and available.
|
|
30
|
-
If this is intended, please install the gem.
|
|
31
|
-
TEXT
|
|
32
|
-
raise DiceyError, "can not roll dice with non-numeric sides!"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def die_foundry
|
|
38
|
-
@die_foundry ||= DieFoundry.new
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def roll_dice(dice)
|
|
42
|
-
dice = vectorize_dice(dice) if defined?(VectorNumber)
|
|
43
|
-
dice.sum(&:roll)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "brute_force"
|
|
4
|
-
require_relative "kronecker_substitution"
|
|
5
|
-
require_relative "multinomial_coefficients"
|
|
6
|
-
|
|
7
|
-
module Dicey
|
|
8
|
-
module SumFrequencyCalculators
|
|
9
|
-
# Tool to automatically select a calculator for a given set of dice.
|
|
10
|
-
#
|
|
11
|
-
# Calculator is guaranteed to be compatible, with a strong chance of being the most performant.
|
|
12
|
-
#
|
|
13
|
-
# @see BaseCalculator#heuristic_complexity
|
|
14
|
-
class AutoSelector
|
|
15
|
-
# Calculators to consider when selecting a match.
|
|
16
|
-
AVAILABLE_CALCULATORS = [
|
|
17
|
-
KroneckerSubstitution.new,
|
|
18
|
-
MultinomialCoefficients.new,
|
|
19
|
-
BruteForce.new,
|
|
20
|
-
].freeze
|
|
21
|
-
|
|
22
|
-
# @param calculators [Array<BaseCalculator>]
|
|
23
|
-
# calculators which this instance will consider
|
|
24
|
-
def initialize(calculators = AVAILABLE_CALCULATORS)
|
|
25
|
-
@calculators = calculators
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Determine best (or adequate) calculator for a given set of dice
|
|
29
|
-
# based on heuristics from the list of available calculators.
|
|
30
|
-
#
|
|
31
|
-
# @param dice [Enumerable<NumericDie>]
|
|
32
|
-
# @return [BaseCalculator, nil] +nil+ if no calculator is compatible
|
|
33
|
-
def call(dice)
|
|
34
|
-
compatible = @calculators.select { _1.valid_for?(dice) }
|
|
35
|
-
return if compatible.empty?
|
|
36
|
-
|
|
37
|
-
compatible.min_by { _1.heuristic_complexity(dice) }
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "base_calculator"
|
|
4
|
-
|
|
5
|
-
require_relative "../mixins/vectorize_dice"
|
|
6
|
-
|
|
7
|
-
module Dicey
|
|
8
|
-
module SumFrequencyCalculators
|
|
9
|
-
# Calculator for a collection of {AbstractDie} using exhaustive search (very slow).
|
|
10
|
-
#
|
|
11
|
-
# If dice include non-numeric sides, gem +vector_number+ has to be installed.
|
|
12
|
-
class BruteForce < BaseCalculator
|
|
13
|
-
include Mixins::VectorizeDice
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def validate(dice)
|
|
18
|
-
if defined?(VectorNumber) || dice.all?(NumericDie)
|
|
19
|
-
true
|
|
20
|
-
else
|
|
21
|
-
warn <<~TEXT
|
|
22
|
-
Dice with non-numeric sides need gem "vector_number" to be present and available.
|
|
23
|
-
If this is intended, please install the gem.
|
|
24
|
-
TEXT
|
|
25
|
-
false
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def calculate_heuristic(dice_count, sides_count)
|
|
30
|
-
1000 * (sides_count**dice_count)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def calculate(dice, **nil)
|
|
34
|
-
dice = vectorize_dice(dice) if defined?(VectorNumber)
|
|
35
|
-
dice.map(&:sides_list).reduce { |result, die|
|
|
36
|
-
result.flat_map { |roll| die.map { |side| roll + side } }
|
|
37
|
-
}.tally
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|