Last active
June 18, 2019 14:02
-
-
Save jeremyf/3e764d8eb8a9e7003e20df8a8285f837 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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