48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
DROPS_BASE,
|
|
DROPS_MAX,
|
|
NOTE_VALUES,
|
|
rollDrops,
|
|
} from '../src/rules/floorScore';
|
|
import { SeededRNG } from '../src/core/SeededRNG';
|
|
|
|
describe('the floor score', () => {
|
|
it('a busier night is a messier floor, up to a limit', () => {
|
|
const rng = new SeededRNG(1);
|
|
expect(rollDrops(rng.stream('a'), 0).length).toBe(DROPS_BASE);
|
|
expect(rollDrops(rng.stream('b'), 24).length).toBe(DROPS_BASE + 4);
|
|
expect(rollDrops(rng.stream('c'), 500).length).toBe(DROPS_MAX);
|
|
});
|
|
|
|
it('is deterministic per stream — the same night drops the same floor', () => {
|
|
const a = rollDrops(new SeededRNG(7).stream('sweep'), 40);
|
|
const b = rollDrops(new SeededRNG(7).stream('sweep'), 40);
|
|
expect(a).toEqual(b);
|
|
});
|
|
|
|
it('cash is real denominations; curios, phones and baggies are worth $0', () => {
|
|
for (let seed = 1; seed <= 20; seed++) {
|
|
for (const d of rollDrops(new SeededRNG(seed).stream('s'), 60)) {
|
|
if (d.kind === 'note') expect(NOTE_VALUES).toContain(d.value);
|
|
else if (d.kind === 'coins') expect(d.value).toBeGreaterThan(0);
|
|
else expect(d.value).toBe(0);
|
|
}
|
|
}
|
|
});
|
|
|
|
it('at most one baggie and one phone per night', () => {
|
|
for (let seed = 1; seed <= 30; seed++) {
|
|
const drops = rollDrops(new SeededRNG(seed).stream('s'), 60);
|
|
expect(drops.filter((d) => d.kind === 'baggie').length).toBeLessThanOrEqual(1);
|
|
expect(drops.filter((d) => d.kind === 'phone').length).toBeLessThanOrEqual(1);
|
|
}
|
|
});
|
|
|
|
it('every drop has words — the label IS the reward for curios', () => {
|
|
for (const d of rollDrops(new SeededRNG(11).stream('s'), 30)) {
|
|
expect(d.label.length).toBeGreaterThan(5);
|
|
}
|
|
});
|
|
});
|