fuzzyworld

explodorama / files / test / ruleCompare.test.ts

ruleCompare.test.ts

2.0 KB · history · blame

1import { describe, expect, it } from 'vitest'
2import { readFileSync } from 'node:fs'
3import { compareRules, type Engine } from '../src/sim/ruleCompare'
4import type { RunRecord } from '../src/sim/record'
5import { newRun } from '../src/sim/state'
6import { step } from '../src/sim/turn'
7
8const record = JSON.parse(readFileSync(new URL('./fixtures/q101-bomb-pass.json', import.meta.url), 'utf8')) as RunRecord
9const today: Engine = { newRun, step }
10
11describe('comparing two versions of the rules (Q103)', () => {
12 it('finds no split when both versions are the same', () => {
13 const c = compareRules(today, today, record)
14 expect(c.split).toBeNull()
15 expect(c.red.results).toHaveLength(record.actions.length)
16 expect(c.blue.refused).toBeNull()
17 })
18
19 it('finds the first turn where one version plays differently', () => {
20 // A version that refuses the 60th turn of the run stands in for a rules change.
21 const strict: Engine = {
22 newRun,
23 step: (s, a) => {
24 if (s.runTurns === 60 && a.id !== 'choose' && a.id !== 'continue') throw new Error('not allowed in this version')
25 return step(s, a)
26 },
27 }
28 const c = compareRules(today, strict, record)
29 expect(c.split).not.toBeNull()
30 expect(c.why).toContain("blue's rules refuse it")
31 expect(c.blue.refused?.at).toBe(c.split)
32 expect(c.red.refused).toBeNull()
33 })
34
35 it('finds a split in the game itself when a rule changes what happens', () => {
36 // A version in which a Wait also costs a coin.
37 const taxed: Engine = {
38 newRun,
39 step: (s, a) => {
40 const r = step(s, a)
41 if (a.id === 'wait' && r.state.coins > 0) r.state.coins--
42 return r
43 },
44 }
45 const c = compareRules(today, taxed, record)
46 expect(c.split).not.toBeNull()
47 expect(c.why).toMatch(/coins/)
48 // Before that turn the games agree: replaying up to it gives the same states.
49 expect(c.red.results[c.split! - 1]!.state.coins).toBe(c.blue.results[c.split! - 1]!.state.coins)
50 })
51})