Class: GamesDice::DieResult

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/games_dice/die_result.rb

Overview

This class models the output of GamesDice::ComplexDie.

An object of the class represents the results of a roll of a ComplexDie, including any re-rolls and value mapping.

Examples:

Building up a result manually

dr = GamesDice::DieResult.new
dr.add_roll 5
dr.add_roll 4, :reroll_replace
dr.value # => 4
dr.rolls # => [5, 4]
dr.roll_reasons # => [:basic, :reroll_replace]
# dr can behave as dr.value due to coercion and support for some operators
dr + 6 # => 10

Using a result from GamesDice::ComplexDie

# An "exploding" six-sided die that needs a result of 8 to score "1 Success"
d = GamesDice::ComplexDie.new( 6, :rerolls => [[6, :<=, :reroll_add]], :maps => [[8, :<=, 1, 'Success']] )
# Generate result object by rolling the die
dr = d.roll
dr.rolls         # => [6, 3]
dr.roll_reasons  # => [:basic, :reroll_add]
dr.total         # => 9
dr.value         # => 1
dr.explain_value # => "[6+3] 9 Success"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(first_roll_result = nil, first_roll_reason = :basic) ⇒ GamesDice::DieResult

Creates new instance of GamesDice::DieResult. The object can be initialised “empty” or with a first result.


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/games_dice/die_result.rb', line 35

def initialize( first_roll_result=nil, first_roll_reason=:basic )
  unless GamesDice::REROLL_TYPES.has_key?(first_roll_reason)
    raise ArgumentError, "Unrecognised reason for roll #{first_roll_reason}"
  end

  if (first_roll_result)
    @rolls = [Integer(first_roll_result)]
    @roll_reasons = [first_roll_reason]
    @total = @rolls[0]
  else
    @rolls = []
    @roll_reasons = []
    @total = nil
  end
  @mapped = false
  @value = @total
end

Instance Attribute Details

#mappedBoolean (readonly)

Whether or not #value has been mapped from #total.


71
72
73
# File 'lib/games_dice/die_result.rb', line 71

def mapped
  @mapped
end

#roll_reasonsArray<Symbol> (readonly)

The individual reasons for each roll of the die. See GamesDice::RerollRule for allowed values.


59
60
61
# File 'lib/games_dice/die_result.rb', line 59

def roll_reasons
  @roll_reasons
end

#rollsArray<Integer> (readonly)

The individual die rolls that combined to generate this result.


55
56
57
# File 'lib/games_dice/die_result.rb', line 55

def rolls
  @rolls
end

#totalInteger? (readonly)

Combined result of all rolls, before mapping.


63
64
65
# File 'lib/games_dice/die_result.rb', line 63

def total
  @total
end

#valueInteger? (readonly)

Combined result of all rolls, after mapping.


67
68
69
# File 'lib/games_dice/die_result.rb', line 67

def value
  @value
end

Instance Method Details

#add_roll(roll_result, roll_reason = :basic) ⇒ Integer

Adds value from a new roll to the object. GamesDice::DieResult tracks reasons for the roll and makes the correct adjustment to the total so far. Any mapped value is cleared.


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/games_dice/die_result.rb', line 78

def add_roll( roll_result, roll_reason=:basic )
  unless GamesDice::REROLL_TYPES.has_key?(roll_reason)
    raise ArgumentError, "Unrecognised reason for roll #{roll_reason}"
  end
  @rolls << Integer(roll_result)
  @roll_reasons << roll_reason
  if @rolls.length == 1
    @total = 0
  end

  case roll_reason
  when :basic
    @total = roll_result
  when :reroll_add
    @total += roll_result
  when :reroll_subtract
    @total -= roll_result
  when :reroll_new_die
    @total = roll_result
  when :reroll_new_keeper
    @total = roll_result
  when :reroll_replace
    @total = roll_result
  when :reroll_use_best
    @total = [@value,roll_result].max
  when :reroll_use_worst
    @total = [@value,roll_result].min
  end

  @mapped = false
  @value = @total
end

#apply_map(to_value, description = '') ⇒ nil

Sets value arbitrarily, and notes that the value has been mapped. Used by GamesDice::ComplexDie when there are one or more GamesDice::MapRule objects to process for a die.


116
117
118
119
120
121
# File 'lib/games_dice/die_result.rb', line 116

def apply_map( to_value, description = '' )
  @mapped = true
  @value = to_value
  @map_description = description
  return
end

#cloneGamesDice::DieResult

This is a deep clone, all attributes are cloned.


179
180
181
182
183
184
185
186
187
188
# File 'lib/games_dice/die_result.rb', line 179

def clone
  cloned = GamesDice::DieResult.new()
  cloned.instance_variable_set('@rolls', @rolls.clone)
  cloned.instance_variable_set('@roll_reasons', @roll_reasons.clone)
  cloned.instance_variable_set('@total', @total)
  cloned.instance_variable_set('@value', @value)
  cloned.instance_variable_set('@mapped', @mapped)
  cloned.instance_variable_set('@map_description', @map_description)
  cloned
end

#explain_valueString

Generates a text description of how #value is determined. If #value has been mapped, includes the map description, but does not include the mapped value.


126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/games_dice/die_result.rb', line 126

def explain_value
  text = ''
  if @rolls.length < 2
    text = @total.to_s
  else
    text = '[' + @rolls[0].to_s
    text = (1..@rolls.length-1).inject( text ) { |so_far,i| so_far + GamesDice::REROLL_TYPES[@roll_reasons[i]] + @rolls[i].to_s }
    text += '] ' + @total.to_s
  end
  text += ' ' + @map_description if @mapped && @map_description && @map_description.length > 0
  return text
end