nunof07/smalltypes

View on GitHub
src/main/random/ParkMillerRandom.ts

Summary

Maintainability
A
0 mins
Test Coverage
import {
    Random,
    Scalar,
    ScalarLike,
    ScalarOf
} from '@main';

/**
 * Park-Miller random source.
 * @see http://www.firstpr.com.au/dsp/rand31/
 *
 * For other alternative implementations in JS:
 * @see https://github.com/odogono/prng-parkmiller-js
 * @see https://github.com/SirAnthony/rand31
 * @see https://gist.github.com/blixt/f17b47c62508be59987b
 */
export class ParkMillerRandom implements Random {
    /**
     * Maximum (exclusive) possible value.
     */
    private static readonly MAX: number = 2147483647;

    /**
     * Next seed.
     */
    // tslint:disable-next-line:readonly-keyword
    private seed: Scalar<number>;

    /**
     * Ctor.
     * @param seed Seed number. If not provided will use a seed based on the current time.
     */
    constructor(seed: ScalarLike<number> = (): number => Date.now()) {
        // make sure seed is number between 1 and MAX
        this.seed = new ScalarOf((): number => {
            let source: number = new ScalarOf(seed).value();
            source = (source === 0 ? 1 : source);

            return Math.abs(source) % ParkMillerRandom.MAX;
        });
    }

    /**
     * Next random value between 0 (inclusive) and 1 (exclusive).
     */
    public next(): number {
        this.seed = new ScalarOf((this.seed.value() * 16807) % ParkMillerRandom.MAX);

        return this.seed.value() / ParkMillerRandom.MAX;
    }
}