class Roll
  include Enumerable

  def initialize(num_of_dice, options = { :die_size => 10, :rand_generator => Random})
    @options = options
    @rand_generator = @options[:rand_generator]
    @dice = roll(num_of_dice)
  end

  def reroll(*values)
    each_die_that_matches(values) { roll_die }
    self
  end

  def explode(*values)
    each_die_that_matches(values) { |die| last_die = roll_die; [die + last_die, last_die] }
    self
  end

  def ==(other)
    @dice == other
  end

  def each
    @dice.each { |die| yield die }
  end

  private

  def roll(number)
    number.times.collect { roll_die } 
  end

  def roll_die
    @rand_generator.rand(@options[:die_size])
  end

  def each_die_that_matches(values)
    @dice.map! do |die|
      last_die = die
      while values.any? { |value| value == last_die}
        die, last_die = yield(die)
        last_die = (last_die.nil? && die) || last_die
      end
      die
    end
  end
end