module watt.math.random

A psuedo-random number generator.

A psuedorandom number generator generates a sequence of numbers. The numbers give the impression of randomness, and will be uniformly distributed.

The generator in this module is instanced, not global. That is to say, you declare a struct, and it holds the RNG state:

rng: RandomGenerator;
rng.seed(32);
val := rnd.uniformI32(0, 100);

Given the same seed, a RNG should generate the same sequence of numbers. Often, the output of the C library function time is used to get a random seed value, but this is not ideal. Operating Systems usually provide hardware randomness, or at least stronger randomness, and using that generator to get a seed value is recommended.

See the module watt.io.seed for a function for retrieving a value for the seed.

Code Map

//! A psuedo-random number generator.
module watt.math.random;


//! The default RandomGenerator.
alias RandomGenerator = MersenneTwisterEngine;

//! A psuedorandom number generator implemented with the Mersenne Twister
//! algorithm.
struct MersenneTwisterEngine
{
public:
	//! The smallest unsigned value this generator can generate.
	enum min;
	//! The largest unsigned value this generator can generate.
	enum max;


public:
	//! Seed this generator with the given 32 bit value.
	fn seed(value: u32) { }
	//! Advance this generator.
	fn popFront() { }
	//! This generator's current value.
	fn front() u32 { }
	//! Copy this generator.
	fn save() MersenneTwisterEngine { }
	//! Is this generator out of values?
	fn empty() bool { }
	//! Generate a u32 value within a range.
	fn uniformU32(lower: u32, upper: u32) u32 { }
	//! Generate an i32 value within a range.
	fn uniformI32(lower: i32, upper: i32) i32 { }
	//! Generate a random string.
	fn randomString(length: size_t) string { }
}
alias RandomGenerator

The default RandomGenerator.

A psuedorandom number generator can be implemented in a variety of different ways.
The only generator implemented at the moment is one implemented using the Mersenne Twister algorithm, but if a better algorithm were to be implemented, using RandomGenerator will allow your code to take advantage without changing the generator used manually.

struct MersenneTwisterEngine

A psuedorandom number generator implemented with the Mersenne Twister algorithm.

enum min

The smallest unsigned value this generator can generate.

enum max

The largest unsigned value this generator can generate.

fn seed(value: u32)

Seed this generator with the given 32 bit value.

The seed value determines the consequent values retrieved from this generator. Given two generators with the same seed, and the same generation functions (uniformI32, etc), both generators will generate the same values.
See watt.io.seed for ways to get a good random seed.

Example

rnga: MersenneTwisterEngine;
rnga.seed(42);
rngb: MersenneTwisterEngine;
rngb.seed(42);
assert(rnga.front == rngb.front);
rnga.popFront(); rngb.popFront();
assert(rnga.front == rngb.front);
fn popFront()

Advance this generator.

Changes the value of front.

Example

rng: RandomGenerator;
a := rng.front;
rng.popFront();
assert(a != rng.front);  // Could very well be true.
fn front() u32

This generator's current value.

Calling this multiple times without calling popFront will result in the same value.

Example

rng: RandomGenerator;
assert(rng.front == rng.front);

Return

The current random value.

fn save() MersenneTwisterEngine

Copy this generator.

Generators are structs, so mutating the value returned by this function (through popFront, etc) will not modify the original generator.

Example

rng: RandomGenerator;
rng2 := rng.save();
while (rng2.front == rng.front) rng2.popFront();
assert(rng2.front != rng.front);

Return

a copy of this generator in its current state.

fn empty() bool

Is this generator out of values?

This will never be true in any current implementation.

fn uniformU32(lower: u32, upper: u32) u32

Generate a u32 value within a range.

Note that lower is inclusive, upper is exclusive.

Return

A value greater than or equal to lower but less than upper.

Side-Effects

  • The generator is advanced. (front will change).

fn uniformI32(lower: i32, upper: i32) i32

Generate an i32 value within a range.

Note that lower is inclusive, upper is exclusive.

Return

A value greater than or equal to lower but less than upper.

Side-Effects

  • The generator is advanced. (front will change).

fn randomString(length: size_t) string

Generate a random string.

The string will be comprised of digits and letters (upper and lowercase) in equal distribution.

Parameters

length

The length of the string to generate, in characters.

Return

A string that is length characters long.

Side-Effects

  • The generator is advanced length times.