lib/hazard.rb in hazard-1.2.1 vs lib/hazard.rb in hazard-1.3.0
- old
+ new
@@ -4,19 +4,25 @@
# This class roll the dice.
#
# @author Cédric ZUGER
class Hazard
+ DICE_NAME_REGEXP = /(d|r|m|s)?(\d*)d(\d+)/.freeze
+
# Regular entry point. This is where you will go when you call Hazard.d6 for instance.
#
# @param method_name [String] the description of the dice. See help for detail.
#
# @return [Object] if detail has been asked, it will return a [RolledDice] object, otherwise it will return an [Integer] containing the sum of the dice.
def self.method_missing( method_name )
- # Transform the method_name to string
method_name = method_name.to_s
- self.roll_dice( method_name )
+
+ if method_name =~ DICE_NAME_REGEXP
+ roll_dice( method_name )
+ else
+ super
+ end
end
# From string entry point, in case you have your dice description in a database for instance.
#
# @param dice_string [String] the description of the dice. See help for detail.
@@ -24,40 +30,55 @@
# @return [Object] if detail has been asked, it will return a [RolledDice] object, otherwise it will return an [Integer] containing the sum of the dice.
def self.from_string( dice_string )
roll_dice( dice_string )
end
+ # Hook the method_missing
+ def self.respond_to_missing?(method_name, include_private = false)
+ method_name.to_s =~ DICE_NAME_REGEXP || super
+ end
+
+ # Roll a dice and return true if you rolled the highest number
+ #
+ # @param dice [Integer] the dice you want to roll.
+ #
+ # @return [Boolean] true if you scored the highest number, false otherwise.
+ def self.lucky?( dice )
+ roll_dice( "d#{dice}" ) == dice
+ end
+
private
# Roll dice according to method name
#
# @param method_name [String] the description of the dice. See help for detail.
#
# @return [Object] if detail has been asked, it will return a [RolledDice] object, otherwise it will return an [Integer] containing the sum of the dice.
def self.roll_dice( method_name )
# Parse the method name to get how many dice and what size of dice was required
- dice_match = method_name.to_s.match( /(d|r|m|s)?(\d*)d(\d+)/ )
- # Raise an error if match fail
- raise "Method mising : #{method_name}" unless dice_match
+ dice_match = method_name.to_s.match DICE_NAME_REGEXP
# Get the roll type
roll_type = dice_match[1]
- splited_result = true if roll_type == 's'
+ splitted_result = true if roll_type == 's'
- # Get the dice amount
- dice_amount = dice_match[2].to_i
- # If no amount is given then the amount is 1
- dice_amount = 1 if dice_amount == 0
# Get the type of dice
dice_type = dice_match[3].to_i
# Rolls the dice
- rolls = ( 1..dice_amount ).map{ Kernel.rand( 1..dice_type ) }
+ rolls = ( 1..dice_amount(dice_match) ).map{ Kernel.rand( 1..dice_type ) }
# Unless splitted_result was requested, return the sum of the rolled dice
- return rolls.reduce(:+) unless splited_result
+ return rolls.reduce(:+) unless splitted_result
# Return a RolledDice otherwise
RolledDice.new( rolls )
+ end
+
+ def self.dice_amount( dice_match )
+ # Get the dice amount
+ dice_amount = dice_match[2].to_i
+ # If no amount is given then the amount is 1
+ dice_amount.zero? ? 1 : dice_amount
end
end