# Prerequisites: You need Ruby 2.4.4 or greater. My recommendation is to install ruby via rbenv (https://github.com/rbenv/rbenv) | |
# To run on the command line: | |
# 1) Download this gist | |
# 2) Run the following command: ruby /path/to/this/file.rb | |
class Scenario | |
attr_reader :failure, :compromised_success, :success, :critical, :total, :pool_size | |
def initialize(pool_size:) | |
@pool_size = pool_size | |
@total = 0 | |
@failure = 0 | |
@compromised_success = 0 | |
@success = 0 | |
@critical = 0 | |
end | |
def add_failure | |
@failure += 1 | |
@total += 1 | |
end | |
def add_compromised_success | |
@compromised_success += 1 | |
@total += 1 | |
end | |
def add_success | |
@success += 1 | |
@total += 1 | |
end | |
def add_critical | |
@critical += 1 | |
@total += 1 | |
end | |
def print | |
puts "-"*80 | |
puts "Pool Size #{pool_size}" | |
puts "Critical \t#{100 * critical / total }%\t#{critical}" | |
puts "Success \t#{100 * success / total }%\t#{success}" | |
puts "Compromised\t#{100 * compromised_success / total}%\t#{compromised_success}" | |
puts "Failure \t#{100 * failure / total }%\t#{failure}" | |
end | |
end | |
# scenarios = {} | |
# @param [Scenario] scenario - The accumulator class that tracks successes/failures for the given results | |
# @param [Array<Array>] result - The dice rolls | |
def evaluate(scenario:, results:) | |
if scenario.pool_size == 0 | |
evaluate_zero(scenario: scenario, results: results) | |
else | |
evaluate_non_zero(scenario: scenario, results: results) | |
end | |
end | |
# Increment the corresponding scenario based on the given results. | |
def evaluate_non_zero(scenario:, results:) | |
results.each do |result| | |
result.sort! | |
first = result[-1] | |
second = result[-2] | |
if first == 6 | |
if second == 6 | |
scenario.add_critical | |
else | |
scenario.add_success | |
end | |
elsif first > 3 | |
scenario.add_compromised_success | |
else | |
scenario.add_failure | |
end | |
end | |
end | |
def evaluate_zero(scenario:, results:) | |
results.each do |result| | |
result.sort! | |
first = result[0] | |
if first == 6 | |
scenario.add_success | |
elsif first > 3 | |
scenario.add_compromised_success | |
else | |
scenario.add_failure | |
end | |
end | |
end | |
# This method builds all possible results based on the pool_size. For example, if I have a dice pool of one, | |
# I would have the following array of arrays: [[1],[2],[3],[4],[5],[6]] | |
# If I have a dice pool of two, I would have the following array of arrays: [[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[2,1]…] | |
def build_all_results(pool_size:) | |
array = Array.new(6**pool_size) { Array.new(pool_size) } | |
array.each_with_index do |row, index| | |
(0...pool_size).each do |element| | |
row[-1 * (element + 1)] = ((index / (6**element).to_f).floor) % 6 + 1 | |
end | |
end | |
array | |
end | |
scenarios = [] | |
POOL_SIZES = (1..6) | |
POOL_SIZES.each do |pool_size| | |
results = build_all_results(pool_size: pool_size) | |
# The results array are the same for pool size 0 or pool size 2; Just a matter of how we sort | |
if pool_size == 2 | |
scenario = Scenario.new(pool_size: 0) | |
evaluate(scenario: scenario, results: results) | |
scenarios << scenario | |
end | |
scenario = Scenario.new(pool_size: pool_size) | |
evaluate(scenario: scenario, results: results) | |
scenarios << scenario | |
end | |
scenarios.sort { |a,b| a.pool_size <=> b.pool_size }.each do |scenario| | |
scenario.print | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment