Class: FibonacciRng

Inherits:
Object
  • Object
show all
Defined in:
lib/fibonacci_rng.rb,
lib/fibonacci_rng/version.rb

Overview

The class of Fibonacci inspired random number generators.

Constant Summary collapse

CHOP =
0x1FFFFFFF
BYTE =
0xFF
WORD =
0xFFFF
BASE =
(CHOP+1).to_f
VERSION =
"0.0.5"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seed = FibonacciRng.new_seed, depth = 8) ⇒ FibonacciRng

Initialize the PRN generator



44
45
46
47
48
# File 'lib/fibonacci_rng.rb', line 44

def initialize(seed=FibonacciRng.new_seed, depth=8)
  fail "Invalid depth value (3..30)." unless (3..30) === depth
  @depth = depth
  srand(seed)
end

Instance Attribute Details

#depthObject (readonly)

An accessor for the depth!



38
39
40
# File 'lib/fibonacci_rng.rb', line 38

def depth
  @depth
end

#seedObject (readonly)

An accessor for the seed value!



41
42
43
# File 'lib/fibonacci_rng.rb', line 41

def seed
  @seed
end

Class Method Details

.new_seedObject

Create the default seed string.



12
13
14
# File 'lib/fibonacci_rng.rb', line 12

def self.new_seed
  Time.now.to_s + @tickle.succ!
end

.rand(max = 0) ⇒ Object

Get a random number from the class based generator. This exists only for compatibility purposes. It is far better to create instances of generators than to use a shared, global one.



19
20
21
# File 'lib/fibonacci_rng.rb', line 19

def self.rand(max=0)
  (@hidden ||= FibonacciRng.new).rand(max)
end

.srand(seed = FibonacciRng.new_seed, depth = 8) ⇒ Object

Initialize the class based generator. This exists only for compatibility purposes. It is far better to create instances of generators than to use a shared, global one.



26
27
28
29
30
# File 'lib/fibonacci_rng.rb', line 26

def self.srand(seed=FibonacciRng.new_seed, depth=8)
  old = (@hidden && @hidden.seed)
  @hidden = FibonacciRng.new(seed, depth)
  old
end

Instance Method Details

#byteObject

Get a pseudo random byte



85
86
87
88
# File 'lib/fibonacci_rng.rb', line 85

def byte
  do_spin
  @buffer[0] & BYTE
end

#bytes(length) ⇒ Object

Get a string of random bytes



91
92
93
94
95
# File 'lib/fibonacci_rng.rb', line 91

def bytes(length)
  result = ""
  length.times {result << byte.chr}
  result
end

#dice(sides) ⇒ Object

Roll a dice.



74
75
76
77
78
79
80
81
82
# File 'lib/fibonacci_rng.rb', line 74

def dice(sides)
  limit = ((CHOP+1) / sides) * sides

  begin
    do_spin
  end until (value = @buffer[0]) < limit

  value % sides
end

#floatObject

Get a pseudo random float



104
105
106
107
# File 'lib/fibonacci_rng.rb', line 104

def float
  do_spin
  @buffer[0].to_f / BASE
end

#rand(max = 0) ⇒ Object

A (mostly) compatible access point for random numbers.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fibonacci_rng.rb', line 60

def rand(max=0)
  @hidden ||= FibonacciRng.new

  if max.is_a?(Range)
    min = max.min
    @hidden.dice(1 + max.max - min) + min
  elsif max == 0
    @hidden.float
  else
    @hidden.dice(max.to_i)
  end
end

#spin(count = 1) ⇒ Object

Cycle through the PRNG count times.



110
111
112
113
114
# File 'lib/fibonacci_rng.rb', line 110

def spin(count=1)
  count.times do
    do_spin
  end
end

#srand(seed = FibonacciRng.new_seed) ⇒ Object

Set up a new seed value



51
52
53
54
55
56
57
# File 'lib/fibonacci_rng.rb', line 51

def srand(seed=FibonacciRng.new_seed)
  @seed = seed
  @buffer = Array.new(@depth+2, 0)
  seedsrc = (seed.to_s + seed.class.to_s + 'Leonardo Pisano').each_byte.cycle
  indxsrc = (0...depth).cycle
  do_reseed(indxsrc, seedsrc)
end

#wordObject

Get a pseudo random word



98
99
100
101
# File 'lib/fibonacci_rng.rb', line 98

def word
  do_spin
  @buffer[0] & WORD
end