module DiceBag
This defined the main DiceBag
module.
This continues definining the DiceBag
module.
Constants
- DEFAULT_ROLL
Public Class Methods
# File lib/dicebag.rb, line 48 def self.normalize(part) [ normalize_op(part.first), normalize_value(part.last) ] end
Make sure there are enough dice to handle both Drop and Keep values. If not, both are reset to 0. Harsh.
# File lib/dicebag.rb, line 141 def self.normalize_drop_keep(hash) drop = hash[:options].fetch(:drop, 0) keep = hash[:options].fetch(:keep, 0) if (drop + keep) >= hash[:count] hash[:options][:drop] = 0 hash[:options][:keep] = 0 hash[:notes].push 'Drop and Keep Conflict. Both reset to 0.' end end
Prevent Explosion abuse.
# File lib/dicebag.rb, line 117 def self.normalize_explode(hash) return unless hash[:options].key? :explode if hash[:options][:explode] == 1 hash[:options][:explode] = hash[:sides] hash[:notes].push("Explode set to #{hash[:sides]}") end end
# File lib/dicebag.rb, line 55 def self.normalize_op(op) # We swap out the strings for symbols. # If the op is not one of the arithimetic # operators, then the op itself is returned. # (This should only happen on :start arrays.) case op when '+' then :add when '-' then :sub when '*' then :mul when '/' then :div else op end end
# File lib/dicebag.rb, line 103 def self.normalize_options(hash) if hash[:options].empty? hash.delete(:options) else normalize_explode hash normalize_reroll hash normalize_drop_keep hash normalize_target hash end hash end
Prevent Reroll abuse.
# File lib/dicebag.rb, line 128 def self.normalize_reroll(hash) return unless hash[:options].key? :reroll if hash[:options][:reroll] >= hash[:sides] hash[:options][:reroll] = 0 hash[:notes].push 'Reroll reset to 0.' end end
Finally, if we have a target number, make sure it is equal to or less than the dice sides and greater than 0, otherwise, set it to 0 (aka no target number) and add a note.
# File lib/dicebag.rb, line 158 def self.normalize_target(hash) return unless hash[:options].key? :target target = hash[:options][:target] return if target >= 0 && target <= hash[:sides] hash[:options][:target] = 0 hash[:notes].push 'Target number too large or is negative; reset to 0.' end
This takes the parsed tree, AFTER it has been through the Transform
class, and massages the data a bit more, to ease the iteration that happens in the Roll
class. It will convert all values into the correct *Part class.
# File lib/dicebag.rb, line 42 def self.normalize_tree(tree) tree = [tree] unless tree.first.is_a? Array tree.map { |part| normalize part } end
# File lib/dicebag.rb, line 70 def self.normalize_value(val) case val when String LabelPart.new val when Hash RollPart.new normalize_xdx(val) when Integer StaticPart.new val else val end end
This further massages the xDx hashes.
# File lib/dicebag.rb, line 84 def self.normalize_xdx(hash) count = hash[:xdx][:count] sides = hash[:xdx][:sides] # Delete the no longer needed :xdx key. hash.delete(:xdx) # Default to at least 1 die. count = 1 if count.zero? || count.nil? # Set the :count and :sides keys directly # and set the notes array. hash[:count] = count hash[:sides] = sides hash[:notes] = [] normalize_options hash end
This is the wrapper for the parse, transform, and normalize calls. This is called by the Roll
class, but may be called to get the raw returned array of parsed bits for other purposes.
# File lib/dicebag.rb, line 174 def self.parse(dstr = '') tree = Parser.new.parse(dstr) ast = Transform.new.apply(tree) normalize_tree ast end
# File lib/dicebag.rb, line 181 def self.roll(dstr = '') Roll.new(dstr).roll end