Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# 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
You can’t perform that action at this time.