boardgame-core/tests/utils/rng.test.ts

93 lines
2.9 KiB
TypeScript
Raw Normal View History

2026-04-01 17:34:21 +08:00
import { describe, it, expect } from 'vitest';
import { createRNG } from '../../src/utils/rng';
describe('createRNG', () => {
it('should create RNG with default seed', () => {
const rng = createRNG();
expect(rng.getSeed()).toBe(1);
});
it('should create RNG with custom seed', () => {
const rng = createRNG(12345);
expect(rng.getSeed()).toBe(12345);
});
it('should generate numbers in range [0, 1)', () => {
const rng = createRNG(42);
for (let i = 0; i < 100; i++) {
const num = rng.next();
expect(num).toBeGreaterThanOrEqual(0);
expect(num).toBeLessThan(1);
}
});
it('should generate numbers with max parameter', () => {
const rng = createRNG(42);
for (let i = 0; i < 100; i++) {
const num = rng.next(100);
expect(num).toBeGreaterThanOrEqual(0);
expect(num).toBeLessThan(100);
}
});
it('should generate integers in range [0, max)', () => {
const rng = createRNG(42);
for (let i = 0; i < 100; i++) {
const num = rng.nextInt(10);
expect(Number.isInteger(num)).toBe(true);
expect(num).toBeGreaterThanOrEqual(0);
expect(num).toBeLessThan(10);
}
});
it('should be deterministic with same seed', () => {
const rng1 = createRNG(12345);
const rng2 = createRNG(12345);
const sequence1 = Array.from({ length: 10 }, () => rng1.next());
const sequence2 = Array.from({ length: 10 }, () => rng2.next());
expect(sequence1).toEqual(sequence2);
});
it('should produce different sequences with different seeds', () => {
const rng1 = createRNG(12345);
const rng2 = createRNG(54321);
const sequence1 = Array.from({ length: 10 }, () => rng1.next());
const sequence2 = Array.from({ length: 10 }, () => rng2.next());
expect(sequence1).not.toEqual(sequence2);
});
it('should reset seed with setSeed', () => {
const rng = createRNG(42);
const firstSequence = Array.from({ length: 5 }, () => rng.next());
rng.setSeed(42);
const secondSequence = Array.from({ length: 5 }, () => rng.next());
expect(firstSequence).toEqual(secondSequence);
});
it('should generate uniformly distributed integers', () => {
const rng = createRNG(42);
const buckets = new Array(10).fill(0);
const iterations = 10000;
for (let i = 0; i < iterations; i++) {
const num = rng.nextInt(10);
buckets[num]++;
}
// 每个桶应该大约有 10% 的值
const expected = iterations / 10;
const tolerance = expected * 0.3; // 30% 容差
buckets.forEach((count, index) => {
expect(count).toBeGreaterThan(expected - tolerance);
expect(count).toBeLessThan(expected + tolerance);
});
});
});