import { describe, expect, it } from 'vitest' import { World } from '../src/renderer/game/engine/runtime/World' import { WorldSim } from '../src/renderer/game/engine/sim/WorldSim' import { monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation' 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' }) } describe('矩阵:多纪元世界检查', () => { it.each(Array.from({ length: 12 }, (_, i) => [i * 37 + 11] as const))( 'seed %d:50 年检查点(家数/era/池/景气域)', (seed) => { const w = mk(`ep-${seed}`) for (let i = 0; i < 600; i++) { w.advanceMonth() let g = 0 while (w.state.pendingEvent && g < 4) { w.applyEventChoice(w.state.pendingEvent, 0); g++ } } const ws = w.state.worldSim as { marketPool?: Record; era?: string; npcDyn?: Record } const home = Object.keys(w.state.npcFamilies).length expect(home).toBeGreaterThanOrEqual(2) expect(['shengshi', 'pingshi', 'luanshi', 'mofa']).toContain(ws.era ?? 'pingshi') for (const v of Object.values(ws.marketPool ?? {})) { expect(Number.isFinite(v as number)).toBe(true) expect((v as number)).toBeGreaterThan(0) } for (const d of Object.values(ws.npcDyn ?? {})) { expect(d.prosperity).toBeGreaterThanOrEqual(8) expect(d.prosperity).toBeLessThanOrEqual(100) } }) it.each(Array.from({ length: 6 }, (_, i) => [i * 101 + 3] as const))( 'seed %d:季度推进 12 月内月度合法性', (seed) => { const w = mk(`qt-${seed}`) for (let i = 0; i < 12; i++) { const before = w.state.month w.advanceMonth() expect(w.state.month).toBeGreaterThanOrEqual(1) expect(w.state.month).toBeLessThanOrEqual(12) expect(w.state.seq).toBeGreaterThan(0) void before } }) it.each(Array.from({ length: 6 }, (_, i) => [i * 55 + 7] as const))( 'seed %d:100 年世界快照结构体(snapshot 消费)', (seed) => { const w = mk(`sn-${seed}`) for (let i = 0; i < 1200; i++) { w.advanceMonth() let g = 0 while (w.state.pendingEvent && g < 4) { w.applyEventChoice(w.state.pendingEvent, 0); g++ } } const snap = new WorldSim(w).snapshot() expect(snap.era.length).toBeGreaterThan(0) expect(snap.npcs.length).toBeGreaterThanOrEqual(2) expect(snap.annals.length).toBeGreaterThanOrEqual(3) }) }) describe('矩阵:角色养成组合', () => { it.each([ ['功法一', 't-qinglian', '木'], ['功法二', 't-canglei', '金'], ['功法三', 't-houtu', '土'], ['无功法', undefined, '木'] ] as const)('%s:修为速率分母正', (label, techId, element) => { const w = mk(`tm-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: 'qi', minor: 1 } if (techId) w.giveTechnique(c.id, techId) const rate = monthlyRate(w, c, 1) expect(rate).toBeGreaterThan(0) void element }) it.each([ ['装备凡器', 'weapon-fan'], ['装备法器', 'weapon-qi'], ['装备灵器', 'weapon-ling'], ['装备法宝', 'weapon-fa'] ] as const)('%s:装备战力为正', (label, artifact) => { const w = mk(`aw-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: 'foundation', minor: 1 } w.state.family.inventory[artifact] = 1 w.equip(c.id, artifact) expect(combatPowerOf(w, c)).toBeGreaterThan(0) }) it.each([ ['炼气速修', 'qi', 5], ['筑基速修', 'foundation', 5], ['金丹速修', 'core', 5], ['元婴速修', 'nascent', 5] ] as const)('%s:月率随境界分配正常', (label, major, perception) => { const w = mk(`md-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: major as never, minor: 2 } c.perception = perception expect(monthlyRate(w, c, 1)).toBeGreaterThan(0) }) })