class DiceBag::RollPart

This represents the xDx part of the dice string.

Attributes

count[R]
options[R]
parts[R]
sides[R]
tally[R]

Public Class Methods

new(part) click to toggle source
# File lib/dicebag/roll_part.rb, line 14
def initialize(part)
  @total  = nil
  @tally  = []
  @value  = part
  @count  = part[:count]
  @sides  = part[:sides]
  @notes  = part[:notes] || []

  # Our Default Options
  @options = { explode: 0, drop: 0, keep: 0, reroll: 0, target: 0 }

  @options.update(part[:options]) if part.key?(:options)
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/dicebag/roll_part.rb, line 75
def <=>(other)
  total <=> other.total
end
notes() click to toggle source
# File lib/dicebag/roll_part.rb, line 28
def notes
  @notes.empty? ? '' : @notes.join("\n")
end
roll() click to toggle source
# File lib/dicebag/roll_part.rb, line 46
def roll
  generate_results

  @results.sort!
  @results.reverse!

  # Save the tally in case it's requested later.
  @tally = @results.dup

  # Drop the low end numbers if :drop is not zero.
  handle_drop

  # Keep the high end numbers if :keep is greater than zero.
  handle_keep

  # Set the total.
  handle_total

  self
end
roll_die() click to toggle source

Rolls a single die from the xDx string.

# File lib/dicebag/roll_part.rb, line 39
def roll_die
  num = 0
  num = rand(sides) + 1 while num <= @options[:reroll]

  num
end
rolled?() click to toggle source

Checks to see if this instance has rolled yet or not.

# File lib/dicebag/roll_part.rb, line 34
def rolled?
  @total.nil? ? false : true
end
total() click to toggle source

Gets the total of the last roll; if there is no last roll, it calls roll() first.

# File lib/dicebag/roll_part.rb, line 69
def total
  roll if @total.nil?

  @total
end

Private Instance Methods

generate_results() click to toggle source
# File lib/dicebag/roll_part.rb, line 81
def generate_results
  @results = []

  count.times do
    r = roll_die

    @results.push(r)

    handle_explode(r) unless @options[:explode].zero?
  end
end
handle_drop() click to toggle source
# File lib/dicebag/roll_part.rb, line 101
def handle_drop
  return unless @options[:drop] > 0

  # Note that we invert the drop value here.
  range = 0...-(@options[:drop])

  @results = @results.slice range
end
handle_explode(r) click to toggle source
# File lib/dicebag/roll_part.rb, line 93
def handle_explode(r)
  while r >= @options[:explode]
    r = roll_die

    @results.push(r)
  end
end
handle_keep() click to toggle source
# File lib/dicebag/roll_part.rb, line 110
def handle_keep
  return unless @options[:keep] > 0

  range = 0...@options[:keep]

  @results = @results.slice range
end
handle_total() click to toggle source
# File lib/dicebag/roll_part.rb, line 118
def handle_total
  # If we have a target number, count how many rolls
  # in the results are >= than this number, otherwise
  # we just add up all the numbers.
  @total = if @options[:target] && @options[:target] > 0
             @results.count { |r| r >= @options[:target] }
           else
             # I think reduce(:+) is ugly, but it's very fast.
             @results.reduce(:+)
           end
end