Module: Cinch::Plugins::Dicebag::Die

Defined in:
lib/cinch/plugins/dicebag/die.rb

Overview

Module to manage the actuall roling of specific dice.

Constant Summary collapse

MOD_REGEX =
/[\-\+]\d+/
ROLLS_REGEX =
/(\d+)d\d+/
SIDES_REGEX =
/\d?d(\d+)/

Class Method Summary collapse

Class Method Details

.cast(die) ⇒ Fixnum

Rolls an n-sided die a given amount of times and returns the total

Parameters:

  • count (String)

    Number of times to roll the die.

Returns:

  • (Fixnum)

    The total from rolling the die.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cinch/plugins/dicebag/die.rb', line 40

def self.cast(die)
  # Pull out the data from the roll. 
  modifier = die[MOD_REGEX]
  count = (die[ROLLS_REGEX, 1] || 1).to_i
  sides = die[SIDES_REGEX, 1].to_i

  # init the total
  total = 0

  # Bail if the roll isn't sane looking.
  return total unless check_die_sanity(count, sides)

  # Roll dem dice!
  count.times { total += rand(sides) + 1 }

  # Parse the modifier and apply it, if there is one
  return total += parse_modifier(modifier) unless modifier.nil?

  total
end

.check_die_sanity(count, sides) ⇒ Object

Makes sure people aren’t doing silly things.



62
63
64
65
# File 'lib/cinch/plugins/dicebag/die.rb', line 62

def self.check_die_sanity(count, sides)
  return false if count.nil? || sides.nil? || sides < 1 || count < 1
  true
end

.clean_roll(dice) ⇒ Object

Remove any stupid crap people try to sneak into the rolls.



68
69
70
71
# File 'lib/cinch/plugins/dicebag/die.rb', line 68

def self.clean_roll(dice)
  dice.delete_if { |d| d.match(/\d*d\d+([\-\+]\d+)?/).nil? }
  dice
end

.die_check?(dice) ⇒ Boolean

Takes an array of rolls and does sanity on it.

Parameters:

  • dice (Array)

    Array of strings that correspond to valid die rolls. (i.e. [‘4d6’, ‘6d10’]

Returns:

  • (Boolean)

    Result of sanity check.



77
78
79
80
81
82
# File 'lib/cinch/plugins/dicebag/die.rb', line 77

def self.die_check?(dice)
  # Check to make sure it's not a stupid large roll, they clog threads.
  count = dice.map { |d| d[/(\d+)d\d+/, 1].to_i || 1 }.inject(0, :+)
  return false if count >= 10_000
  true
end

.parse_modifier(modifier) ⇒ Object

Parse out the modified and return it as an int.



85
86
87
88
89
# File 'lib/cinch/plugins/dicebag/die.rb', line 85

def self.parse_modifier(modifier)
  operator = modifier[/\A[\+\-]/]
  int = modifier[/\d+\z/].to_i
  0.send(operator, int)
end

.roll(dice) ⇒ Fixnum

Takes a dice roll string or Array of dice rolls, sanitizes them,

parses them, and dispatches their calculation to `Die.cast`.

Parameters:

  • dice (Array)

    Array of strings that correspond to valid die rolls. (i.e. [‘4d6’, ‘6d10’]

Returns:

  • (Fixnum)

    The total from rolling all of the dice.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/cinch/plugins/dicebag/die.rb', line 15

def self.roll(dice)
  # Convert to an array if it's a single die roll
  dice = [dice] if dice.is_a?(String)

  # Clean out anything invalid
  dice = clean_roll(dice)

  # Initialize a total
  total = nil

  # Return if the sanity fails
  return 'I don\'t have that many dice!' unless die_check?(dice)

  # Roll each group and total up the returned value
  dice.each do |die|
    total ||= 0
    total += cast(die)
  end

  total
end