49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { random, randomInt, weightedPick } from '../../src/sim/rng';
|
|
|
|
describe('rng', () => {
|
|
it('is deterministic for a given seed', () => {
|
|
const a = { rngState: 42 };
|
|
const b = { rngState: 42 };
|
|
const seqA = [random(a), random(a), random(a)];
|
|
const seqB = [random(b), random(b), random(b)];
|
|
expect(seqA).toEqual(seqB);
|
|
});
|
|
|
|
it('returns values in [0, 1)', () => {
|
|
const h = { rngState: 7 };
|
|
for (let i = 0; i < 1000; i++) {
|
|
const v = random(h);
|
|
expect(v).toBeGreaterThanOrEqual(0);
|
|
expect(v).toBeLessThan(1);
|
|
}
|
|
});
|
|
|
|
it('randomInt stays within inclusive bounds', () => {
|
|
const h = { rngState: 1 };
|
|
const seen = new Set<number>();
|
|
for (let i = 0; i < 1000; i++) {
|
|
const v = randomInt(h, 3, 5);
|
|
expect(v).toBeGreaterThanOrEqual(3);
|
|
expect(v).toBeLessThanOrEqual(5);
|
|
seen.add(v);
|
|
}
|
|
expect(seen.size).toBe(3);
|
|
});
|
|
|
|
it('weightedPick never picks zero-weight items', () => {
|
|
const h = { rngState: 3 };
|
|
const items = ['a', 'b', 'c'];
|
|
for (let i = 0; i < 500; i++) {
|
|
const v = weightedPick(h, items, (x) => (x === 'b' ? 0 : 1));
|
|
expect(v).not.toBe('b');
|
|
}
|
|
});
|
|
|
|
it('weightedPick returns undefined when all weights are zero', () => {
|
|
const h = { rngState: 3 };
|
|
expect(weightedPick(h, ['a'], () => 0)).toBeUndefined();
|
|
expect(weightedPick(h, [], () => 1)).toBeUndefined();
|
|
});
|
|
});
|