feat: seeded RNG with per-label deterministic rolls

This commit is contained in:
2026-06-12 13:54:40 +00:00
parent fe28d8ddcb
commit 52d5008cdf
2 changed files with 60 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
// FNV-1a 32-bit string hash.
export function hash32(str) {
let h = 0x811c9dc5;
for (let i = 0; i < str.length; i++) {
h ^= str.charCodeAt(i);
h = Math.imul(h, 0x01000193);
}
return h >>> 0;
}
// mulberry32 PRNG: returns function yielding uniforms in [0,1).
export function makeRng(seed) {
let a = seed >>> 0;
return function () {
a |= 0;
a = (a + 0x6d2b79f5) | 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
// One deterministic uniform in [0,1) for a (seed, label) pair.
// This is the whole hidden-variable mechanism: outcomes are fixed
// the moment their label exists, revealed whenever first asked for.
export function rollFor(seed, label) {
return makeRng(hash32(seed + ':' + label))();
}