Skip to content

Instantly share code, notes, and snippets.

@lodestone
Last active December 19, 2015 04:09
Show Gist options
  • Save lodestone/5894891 to your computer and use it in GitHub Desktop.
Save lodestone/5894891 to your computer and use it in GitHub Desktop.
Simulate dice rolls and generate command line graphs of statistical breakdowns of result sets.
# This allows me to generate output as follows.
#
# For a DiceSet:
#
# <DiceSet:
# @set: [d8=>7, d10=>5, d12=>2, d8=>8, d6=>1]
# @results: {}>
#
# > d=Dice.instance
# > ds=DiceSet.new [d^8, d^10, d^12, d^8]
# > ds.generate_results.graph
#
# Running 100000 times, taking the top 3, the breakdown of results by value rolled are:
# …………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
# 3 ( 0.00%)
# 4 ( 0.01%)
# 5 ( 0.03%)
# 6 ( 0.08%)
# 7 ( 0.21%) °
# 8 ( 0.33%) °
# 9 ( 0.69%) °°°
# 10 ( 1.02%) °°°°°
# 11 ( 1.61%) °°°°°°°°
# 12 ( 2.34%) °°°°°°°°°°°
# 13 ( 3.25%) °°°°°°°°°°°°°°°°
# 14 ( 4.25%) °°°°°°°°°°°°°°°°°°°°°
# 15 ( 5.42%) °°°°°°°°°°°°°°°°°°°°°°°°°°°
# 16 ( 6.29%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 17 ( 7.41%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 18 ( 8.13%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 19 ( 8.74%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 20 ( 8.91%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 21 ( 8.68%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 22 ( 8.06%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 23 ( 6.98%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 24 ( 5.78%) °°°°°°°°°°°°°°°°°°°°°°°°°°°°
# 25 ( 4.41%) °°°°°°°°°°°°°°°°°°°°°°
# 26 ( 3.18%) °°°°°°°°°°°°°°°
# 27 ( 2.14%) °°°°°°°°°°
# 28 ( 1.26%) °°°°°°
# 29 ( 0.56%) °°
# 30 ( 0.19%)
#
# Similar Anydice function here: http://anydice.com/program/25a0
class Dice
include Singleton
def ^(max)
Die.new(max)
end
end
class Die
def initialize(sides)
@sides = sides
@value = rand(1..@sides)
end
def +(x)
return @value+x.value if x.is_a?(Die)
return @value+x if x.is_a?(Fixnum)
end
def inspect; "d#{@sides}=>#{value}"; end
def value; @value; end
def roll; @value = rand(1..@sides); end
def reroll; roll; end
def to_s; value; end
def to_i; value; end
end
class DiceSet
attr_reader :how_many, :top_number_of_dice, :results
attr_writer :how_many, :top_number_of_dice, :results
def initialize(set)
raise 'Dice must be instances of Die, fucker.' unless set.any?{|s| s.is_a?(Die) }
@set = set
@how_many = 100_000
@top_number_of_dice = 2
end
def highest(top: @top_number_of_dice, re_roll: false)
reroll if re_roll
highest_results = @set.sort_by{|d| d.value }.reverse[0..top-1]
return highest_results.map(&:to_i).sum
end
def reroll
@set.map(&:reroll)
self
end
def generate_results
@results = Hash.new(0)
@how_many.times { @results[highest(top: @top_number_of_dice, re_roll: true)] += 1 }
self
end
def graph(r=@results)
raise "There are no statistical results to graph. Run :generate_results" if r.empty?
puts "Running #{@how_many} times, taking the top #{@top_number_of_dice}, the breakdown of results by value rolled are:"
puts "…" * 100
r.sort.each do |r|
percentage = (r[1].to_f/@how_many.to_f)
printf "%5d ", r[0]
print '('
printf "%5.2f", percentage * 100
print "%) "
print '°' * (percentage*500).to_i
print "\n"
end
self
end
def inspect
puts "<DiceSet:\n @set: #{@set.inspect}\n @results: #{@results.inspect}>"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment