Class: Dicey::AbstractDie

Inherits:
Object
  • Object
show all
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:

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

NumericDie

Constant Summary collapse

@@random =

Shared randomness source, accessed through rand and srand.

Random.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sides_list) ⇒ AbstractDie

Returns a new instance of AbstractDie.

Parameters:

  • sides_list (Enumerable<Any>)

Raises:



86
87
88
89
90
91
92
93
94
# File 'lib/dicey/abstract_die.rb', line 86

def initialize(sides_list)
  @sides_list = sides_list.to_a
  @sides_list = @sides_list.dup if @sides_list.equal?(sides_list)
  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_listArray<Any> (readonly)

Die’s list of sides.

Returns:

  • (Array<Any>)


77
78
79
# File 'lib/dicey/abstract_die.rb', line 77

def sides_list
  @sides_list
end

#sides_numInteger (readonly)

Number of sides of the die.

Returns:

  • (Integer)


82
83
84
# File 'lib/dicey/abstract_die.rb', line 82

def sides_num
  @sides_num
end

Class Method Details

.describe(dice) ⇒ String

Get a text representation of a list of dice.

Parameters:

Returns:

  • (String)


49
50
51
52
53
# File 'lib/dicey/abstract_die.rb', line 49

def self.describe(dice)
  return dice.to_s if AbstractDie === dice

  dice.to_a.join("+")
end

.from_count(count, definition) ⇒ Array<AbstractDie>

Create a number of equal dice from one definition.

Parameters:

  • count (Integer)

    number of dice to create

  • definition (Enumerable<Any>, Any)

    definition suitable for the dice class

Returns:



70
71
72
# File 'lib/dicey/abstract_die.rb', line 70

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.

Parameters:

  • definitions (Array<Enumerable<Any>>, Array<Any>)

    list of definitions suitable for the dice class

Returns:



60
61
62
# File 'lib/dicey/abstract_die.rb', line 60

def self.from_list(*definitions)
  definitions.map { new(_1) }
end

.randObject

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.

See Also:

  • Random#rand


30
31
32
# File 'lib/dicey/abstract_die.rb', line 30

def self.rand(...)
  @@random.rand(...)
end

.srandObject

Reset internal randomizer using a new seed.

See Also:

  • Random.new


36
37
38
# File 'lib/dicey/abstract_die.rb', line 36

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.

Parameters:

Returns:

  • (Boolean)

See Also:



137
138
139
# File 'lib/dicey/abstract_die.rb', line 137

def ==(other)
  AbstractDie === other && same_sides?(other)
end

#currentAny

Get current side of the die.

Returns:

  • (Any)

    current side



99
100
101
# File 'lib/dicey/abstract_die.rb', line 99

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.

Parameters:

Returns:

  • (Boolean)

See Also:



151
152
153
# File 'lib/dicey/abstract_die.rb', line 151

def eql?(other)
  self.class === other && same_sides?(other)
end

#hashInteger

Generates an Integer hash value for this object.

Returns:

  • (Integer)


158
159
160
# File 'lib/dicey/abstract_die.rb', line 158

def hash
  [self.class, @sides_list].hash
end

#nextAny

Get next side of the die, advancing internal state. Starts from first side, wraps from last to first side.

Returns:

  • (Any)

    next side



107
108
109
110
111
# File 'lib/dicey/abstract_die.rb', line 107

def next
  ret = current
  @current_side_index = (@current_side_index + 1) % @sides_num
  ret
end

#rollAny

Move internal state to a random side.

Returns:

  • (Any)

    rolled side



116
117
118
119
# File 'lib/dicey/abstract_die.rb', line 116

def roll
  @current_side_index = self.class.rand(@sides_num)
  current
end

#to_sString

Return a string representing the die.

Default representation is a list of sides in round brackets.

Returns:

  • (String)


126
127
128
# File 'lib/dicey/abstract_die.rb', line 126

def to_s
  (@sides_list.size > 1) ? "(#{@sides_list.join(",")})" : "(#{@sides_list.first},)"
end