@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
87 lines (71 loc) • 2.74 kB
JavaScript
/**
* Random number generator based on Mersenne Twister sequence
* @param {number} seed
* @returns {function():number} RNG
*/
export function seededRandom_MersenneTwister(seed) {
// see https://gist.github.com/banksean/300494
/* Period parameters */
const N = 624;
const M = 397;
const MATRIX_A = 0x9908b0df;
/* constant vector a */
const UPPER_MASK = 0x80000000;
/* most significant w-r bits */
const LOWER_MASK = 0x7fffffff;
/* least significant r bits */
const mt = new Array(N);
/* the array for the state vector */
let mti = N + 1;
/* mti==N+1 means mt[N] is not initialized */
function init_genrand(s) {
mt[0] = s >>> 0;
for (mti = 1; mti < N; mti++) {
const s = mt[mti - 1] ^ (mt[mti - 1] >>> 30);
mt[mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)
+ mti;
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
mt[mti] >>>= 0;
/* for >32 bit machines */
}
}
/* generates a random number on [0,0xffffffff]-interval */
function genrand_int32() {
let y;
const mag01 = new Array(0x0, MATRIX_A);
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (mti >= N) { /* generate N words at one time */
let kk;
if (mti === N + 1) /* if init_genrand() has not been called, */{
init_genrand(5489);
}
/* a default initial seed is used */
for (kk = 0; kk < N - M; kk++) {
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk + M] ^ (y >>> 1) ^ mag01[y & 0x1];
}
for (; kk < N - 1; kk++) {
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk + (M - N)] ^ (y >>> 1) ^ mag01[y & 0x1];
}
y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
/* Tempering */
y ^= (y >>> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >>> 18);
return y >>> 0;
}
init_genrand(seed);
function random() {
return genrand_int32() * (1.0 / 4294967296.0);
}
return random;
}