Class: Dicey::AbstractDie
- Inherits:
-
Object
- Object
- Dicey::AbstractDie
- Defined in:
- lib/dicey/abstract_die.rb
Overview
Asbtract die which may have an arbitrary list of sides, not even neccessarily numbers but strings or other objects.
As the base class for all dice, defines their API.
Dice can be created through several methods:
- basic
.new(#initialize), creating one die from an appropriate definition; - AbstractDie.from_list, creating an array of dice from a list of definitions;
- AbstractDie.from_count, creating a number of equal dice from one definition.
Rolling a die is done through #roll. #current returns the current side of the die.
AbstractDie.srand can be used to (re)set the internal randomizer's state for all dice, allowing to reproduce the same sequence of rolls (if it was done with a known state).
Direct Known Subclasses
Constant Summary collapse
- STRING_TO_QUOTE =
Matcher to check whether string needs quoting.
/["',()+−-]/- @@random =
Random.new
Instance Attribute Summary collapse
-
#sides_list ⇒ Array<Any>
readonly
Die's list of sides.
-
#sides_num ⇒ Integer
readonly
Number of sides of the die.
Class Method Summary collapse
-
.describe(dice) ⇒ String
Get a text representation of a list of dice.
-
.from_count(count, definition) ⇒ Array<AbstractDie>
Create a number of equal dice from one definition.
-
.from_list(*definitions) ⇒ Array<AbstractDie>
Create a bunch of different dice at once from a list of definitions.
-
.rand ⇒ Object
private
Get a random value using a private instance of Random.
-
.srand ⇒ Object
Reset internal randomizer using a new seed.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Determine if this die and the other one have the same list of sides.
-
#current ⇒ Any
Get current side of the die.
-
#eql?(other) ⇒ Boolean
Determine if this die and the other one are of the same class and have the same list of sides.
-
#freeze ⇒ Object
Freezes
self(if not already frozen); returnsself. -
#hash ⇒ Integer
Generates an Integer hash value for this object.
-
#initialize(sides_list) ⇒ AbstractDie
constructor
A new instance of AbstractDie.
-
#next ⇒ Any
Get next side of the die, advancing internal state.
-
#numeric? ⇒ Boolean
Whether all sides of this die are
Numeric. -
#roll ⇒ Any
Move internal state to a random side.
-
#to_s ⇒ String
Return a string representing the die.
Constructor Details
#initialize(sides_list) ⇒ AbstractDie
Returns a new instance of AbstractDie.
95 96 97 98 99 100 101 102 103 |
# File 'lib/dicey/abstract_die.rb', line 95 def initialize(sides_list) @sides_list = sides_list.to_a @sides_list = @sides_list.dup if @sides_list.equal?(sides_list) && !@sides_list.frozen? raise DiceyError, "dice must have at least one side!" if @sides_list.empty? @sides_list.freeze @sides_num = @sides_list.size @current_side_index = 0 end |
Instance Attribute Details
#sides_list ⇒ Array<Any> (readonly)
Die's list of sides.
86 87 88 |
# File 'lib/dicey/abstract_die.rb', line 86 def sides_list @sides_list end |
#sides_num ⇒ Integer (readonly)
Number of sides of the die.
91 92 93 |
# File 'lib/dicey/abstract_die.rb', line 91 def sides_num @sides_num end |
Class Method Details
.describe(dice) ⇒ String
Get a text representation of a list of dice.
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/dicey/abstract_die.rb', line 53 def self.describe(dice) return dice.to_s if AbstractDie === dice dice.map(&:to_s).reduce { |string, die| die_string = die.to_s string << "+" unless die_string.match?(/\A[+-]/) string << die_string string }.to_s end |
.from_count(count, definition) ⇒ Array<AbstractDie>
Create a number of equal dice from one definition.
79 80 81 |
# File 'lib/dicey/abstract_die.rb', line 79 def self.from_count(count, definition) Array.new(count) { new(definition) } end |
.from_list(*definitions) ⇒ Array<AbstractDie>
Create a bunch of different dice at once from a list of definitions.
69 70 71 |
# File 'lib/dicey/abstract_die.rb', line 69 def self.from_list(*definitions) definitions.map { new(_1) } end |
.rand ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get a random value using a private instance of Random.
Do not use this method directly. Reproducible rolls depend on it being called only internally.
34 35 36 |
# File 'lib/dicey/abstract_die.rb', line 34 def self.rand(...) @@random.rand(...) end |
.srand ⇒ Object
Reset internal randomizer using a new seed.
40 41 42 |
# File 'lib/dicey/abstract_die.rb', line 40 def self.srand(...) @@random = Random.new(...) end |
Instance Method Details
#==(other) ⇒ Boolean
Determine if this die and the other one have the same list of sides. Be aware that differently ordered sides are not considered equal.
148 149 150 |
# File 'lib/dicey/abstract_die.rb', line 148 def ==(other) AbstractDie === other && same_sides?(other) end |
#current ⇒ Any
Get current side of the die.
108 109 110 |
# File 'lib/dicey/abstract_die.rb', line 108 def current @sides_list[@current_side_index] end |
#eql?(other) ⇒ Boolean
Determine if this die and the other one are of the same class and have the same list of sides. Be aware that differently ordered sides are not considered equal.
die_1.eql?(die_2) implies die_1.hash == die_2.hash.
162 163 164 |
# File 'lib/dicey/abstract_die.rb', line 162 def eql?(other) self.class === other && same_sides?(other) end |
#freeze ⇒ Object
Freezes self (if not already frozen); returns self.
Performs computations that memoize results before freezing.
185 186 187 188 |
# File 'lib/dicey/abstract_die.rb', line 185 def freeze numeric? unless frozen? super end |
#hash ⇒ Integer
Generates an Integer hash value for this object.
169 170 171 |
# File 'lib/dicey/abstract_die.rb', line 169 def hash [self.class, @sides_list].hash end |
#next ⇒ Any
Get next side of the die, advancing internal state. Starts from first side, wraps from last to first side.
116 117 118 119 120 |
# File 'lib/dicey/abstract_die.rb', line 116 def next ret = current @current_side_index = (@current_side_index + 1) % @sides_num ret end |
#numeric? ⇒ Boolean
Whether all sides of this die are Numeric.
176 177 178 179 180 |
# File 'lib/dicey/abstract_die.rb', line 176 def numeric? return @numeric if defined?(@numeric) @numeric = @sides_list.all?(Numeric) end |
#roll ⇒ Any
Move internal state to a random side.
125 126 127 128 |
# File 'lib/dicey/abstract_die.rb', line 125 def roll @current_side_index = self.class.rand(@sides_num) current end |
#to_s ⇒ String
Return a string representing the die.
Default representation is a list of sides in round brackets. Strings are quoted.
136 137 138 139 |
# File 'lib/dicey/abstract_die.rb', line 136 def to_s sides = @sides_list.map { |side| side_to_s(side) } (@sides_list.size > 1) ? "(#{sides.join(",")})" : "(#{sides.first},)" end |