module DiceBag

This defined the main DiceBag module.

This continues definining the DiceBag module.

Constants

DEFAULT_ROLL

Public Class Methods

normalize(part) click to toggle source
# File lib/dicebag.rb, line 48
def self.normalize(part)
  [
    normalize_op(part.first),
    normalize_value(part.last)
  ]
end
normalize_drop_keep(hash) click to toggle source

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
normalize_explode(hash) click to toggle source

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
normalize_op(op) click to toggle source
# 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
normalize_options(hash) click to toggle source
# 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
normalize_reroll(hash) click to toggle source

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
normalize_target(hash) click to toggle source

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
normalize_tree(tree) click to toggle source

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
normalize_value(val) click to toggle source
# 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
normalize_xdx(hash) click to toggle source

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
parse(dstr = '') click to toggle source

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
roll(dstr = '') click to toggle source
# File lib/dicebag.rb, line 181
def self.roll(dstr = '')
  Roll.new(dstr).roll
end