aether-shards/test/utils/SeededRandom.test.js

51 lines
1.4 KiB
JavaScript

/**
* SeededRandom.js
* A deterministic pseudo-random number generator using Mulberry32.
* Essential for reproducible procedural generation.
*/
export class SeededRandom {
constructor(seed) {
// Hash the string seed to a number if necessary
if (typeof seed === "string") {
this.state = this.hashString(seed);
} else {
this.state = seed || Math.floor(Math.random() * 2147483647);
}
}
hashString(str) {
let hash = 1779033703 ^ str.length;
for (let i = 0; i < str.length; i++) {
hash = Math.imul(hash ^ str.charCodeAt(i), 3432918353);
hash = (hash << 13) | (hash >>> 19);
}
// Perform the final mixing immediately and return the result
hash = Math.imul(hash ^ (hash >>> 16), 2246822507);
hash = Math.imul(hash ^ (hash >>> 13), 3266489909);
return hash >>> 0;
}
// Mulberry32 Algorithm
next() {
let t = (this.state += 0x6d2b79f5);
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
}
// Returns float between [min, max)
range(min, max) {
return min + this.next() * (max - min);
}
// Returns integer between [min, max] (inclusive)
rangeInt(min, max) {
return Math.floor(this.range(min, max + 1));
}
// Returns true/false based on probability (0.0 - 1.0)
chance(probability) {
return this.next() < probability;
}
}