import { describe, expect, it } from 'vitest' import { World } from '../src/renderer/game/engine/runtime/World' import { seasonOf } from '../src/renderer/game/data/season' import { ERA_CONF } from '../src/renderer/game/engine/sim/worldsim-data' import { combatPowerOf } from '../src/renderer/game/engine/runtime/Systems/combat' function mk(seed: string): World { return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' }) } const YEAR_CHECKS: Array<[string, number]> = [ ['三年', 3], ['五年', 5], ['十年', 10], ['二十', 20], ['三十', 30], ['四十', 40], ['五十', 50], ['六十', 60], ['七十', 70], ['八十', 80] ] describe('矩阵:轨道年度律法(10 年 × 3)', () => { it.each(YEAR_CHECKS)('%s:推进至 %d 年并验 3 项恒量', (label, years) => { const w = mk(`ry-${label}`) const target = years * 12 for (let i = 0; i < target; i++) { if (w.state.gameOver) break w.advanceMonth() } expect(Number.isFinite(w.state.seq)).toBe(true) expect(Number.isFinite(w.state.family.generation)).toBe(true) expect(Array.isArray(w.state.completedEvents)).toBe(true) }) }) describe('矩阵:成员属性律法(seed × 成员)', () => { it.each(Array.from({ length: 10 }, (_, i) => [i * 3 + 1] as const))( 'seed %d:五代内成员属性恒合法', (seed) => { const w = mk(`mem-${seed}`) for (let i = 0; i < 70; i++) w.advanceMonth() const members = Object.values(w.state.members) expect(members.length).toBeGreaterThan(0) for (const c of members) { expect(typeof c.name).toBe('string') expect(c.realm).toBeTruthy() expect(typeof c.realm.major).toBe('string') expect(typeof c.health).toBe('number') expect(typeof c.mind).toBe('number') expect(typeof c.perception).toBe('number') } }) }) describe('矩阵:时律(节季/时代/灾纪)', () => { it.each(Array.from({ length: 12 }, (_, i) => [i + 1] as const))( '月 %d:季节名称与色相合法', (month) => { expect(['spring', 'summer', 'autumn', 'winter']).toContain(seasonOf(month)) }) it.each([['平世'], ['乱世'], ['末法'], ['盛世']])('%s:时代名枚举在案', (era) => { const conf = ERA_CONF[era as keyof typeof ERA_CONF] if (conf) expect(conf.name.length).toBeGreaterThan(0) }) }) describe('矩阵:存档底线(seed × 槽位交互)', () => { it.each([ ['甲', 'a'], ['乙', 'b'], ['丙', 'c'], ['丁', 'd'] ] as const)('%s:worldGen 摘要存在且四件套齐', (label, seed) => { const w = mk(`sg-${label}-${seed}`) const g = w.state.worldGen expect(g).toBeTruthy() expect(g!.relations).toBeTruthy() expect(typeof g!.npcCount).toBe('number') expect(g!.npcs!.length).toBeGreaterThanOrEqual(4) }) it.each([ ['一代'], ['二代'], ['三代'], ['四代'] ] as const)('%s:世代计数仅增', (label) => { const w = mk(`gn-${label}`) const g0 = w.state.family.generation for (let i = 0; i < 130; i++) w.advanceMonth() expect(w.state.family.generation).toBeGreaterThanOrEqual(g0) }) }) describe('矩阵:战斗与防御', () => { it.each(Array.from({ length: 8 }, (_, i) => [i * 41 + 9] as const))( 'seed %d:组建小队战力聚合为正', (seed) => { const w = mk(`st-${seed}`) const team = Object.values(w.state.members).slice(0, 4) for (const c of team) { expect(combatPowerOf(w, c)).toBeGreaterThan(0) } }) it.each([ ['无备'], ['备战'], ['强备'] ] as const)('%s:防御战(raid)发生不炸', (label) => { const w = mk(`rd-${label}`) for (let i = 0; i < 60; i++) { w.advanceMonth() let g = 0 while (w.state.pendingEvent && g < 4) { w.applyEventChoice(w.state.pendingEvent, 0); g++ } } expect(w.state).toBeTruthy() }) })