import { describe, it, expect } from 'vitest';
import { createRng } from '../rng';
describe('createRng (mulberry32)', () => {
it('одинаковый seed — одинаковая последовательность', () => {
const a = createRng(12345);
const b = createRng(12345);
for (let i = 0; i < 100; i++) {
expect(a.next()).toBe(b.next());
}
});
it('разные seed — разные последовательности', () => {
const a = createRng(1);
const b = createRng(2);
const seqA = Array.from({ length: 10 }, () => a.next());
const seqB = Array.from({ length: 10 }, () => b.next());
expect(seqA).not.toEqual(seqB);
});
it('next в диапазоне 0..1', () => {
const rng = createRng(42);
for (let i = 0; i < 1000; i++) {
const v = rng.next();
expect(v).toBeGreaterThanOrEqual(0);
expect(v).toBeLessThan(1);
}
});
it('int внутри [min, max] включительно', () => {
const rng = createRng(7);
for (let i = 0; i < 500; i++) {
const v = rng.int(2, 5);
expect(v).toBeGreaterThanOrEqual(2);
expect(v).toBeLessThanOrEqual(5);
expect(Number.isInteger(v)).toBe(true);
}
});
it('int достигает обоих концов диапазона', () => {
const rng = createRng(9);
const seen = new Set<number>();
for (let i = 0; i < 500; i++) seen.add(rng.int(1, 3));
expect(seen.has(1)).toBe(true);
expect(seen.has(3)).toBe(true);
});
it('pick берёт элемент из массива', () => {
const rng = createRng(3);
const arr = ['a', 'b', 'c'] as const;
for (let i = 0; i < 50; i++) {
expect(arr).toContain(rng.pick(arr));
}
});
it('pick из пустого массива бросает', () => {
const rng = createRng(3);
expect(() => rng.pick([])).toThrow();
});
it('chance(0) всегда false, chance(1) всегда true', () => {
const rng = createRng(11);
for (let i = 0; i < 100; i++) {
expect(rng.chance(0)).toBe(false);
expect(rng.chance(1)).toBe(true);
}
});
it('state() отражает позицию в последовательности (для сейва в связке с seed)', () => {
const a = createRng(777);
a.next();
const s1 = a.state();
a.next();
const s2 = a.state();
expect(s2).not.toBe(s1);
// тот же seed и те же два вызова дают то же состояние
const b = createRng(777);
b.next();
b.next();
expect(b.state()).toBe(s2);
});
});