import { describe, expect, it } from 'vitest' import { World } from '../src/renderer/game/engine/runtime/World' import { monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation' import { productionTick } from '../src/renderer/game/engine/runtime/Systems/production' function mk(seed: string): World { return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' }) } describe('矩阵:生产季节与建筑', () => { it.each([ ['春', 2], ['夏', 5], ['秋', 8], ['冬', 11] ] as const)('%s:灵田四季产出在有理域(10±季相)', (_label, month) => { const w = mk(`far-${month}`) w.state.month = month w.state.family.buildings = { lingtian: 1 } for (const c of Object.values(w.state.members)) c.realm = { major: 'mortal', minor: 0 } w.state.worldSim = undefined as never const before = w.state.family.inventory['lingcao'] ?? 0 w.advanceMonth() const got = (w.state.family.inventory['lingcao'] ?? 0) - before expect(got).toBeGreaterThan(0) }) it.each([[1, 10], [2, 20], [3, 30], [4, 40], [5, 50]] as const)('灵田 L%d:基础产出 %d 且随等级线性', (lvl, expectOut) => { const w = mk(`ft-${lvl}`) w.state.family.buildings = { lingtian: lvl } for (const c of Object.values(w.state.members)) c.realm = { major: 'mortal', minor: 0 } w.state.worldSim = undefined as never const before = w.state.family.inventory['lingcao'] ?? 0 productionTick(w) const got = (w.state.family.inventory['lingcao'] ?? 0) - before expect(got).toBeGreaterThanOrEqual(expectOut) expect(got).toBeLessThanOrEqual(expectOut * 1.21) // 季相 ±10% 以内 }) it.each([ ['坊市', 'fangshi'], ['灵矿', 'lingkuang'], ['药园', 'yaoyuan'], ['灵兽园', 'lingshou'] ] as const)('%s:L2 级月产有理起步', (label, bld) => { const w = mk(`pb-${label}`) w.state.family.buildings = { [bld]: 2 } for (const c of Object.values(w.state.members)) c.realm = { major: 'mortal', minor: 0 } w.state.worldSim = undefined as never const before = { stones: w.state.family.stones, lingcao: w.state.family.inventory['lingcao'] ?? 0, lingkuang: w.state.family.inventory['lingkuang'] ?? 0, beastcore: w.state.family.inventory['beastcore'] ?? 0 } w.advanceMonth() const after = { stones: w.state.family.stones, lingcao: w.state.family.inventory['lingcao'] ?? 0, lingkuang: w.state.family.inventory['lingkuang'] ?? 0, beastcore: w.state.family.inventory['beastcore'] ?? 0 } expect(after.stones + after.lingcao + after.lingkuang + after.beastcore).toBeGreaterThanOrEqual(before.stones + before.lingcao + before.lingkuang + before.beastcore) }) }) describe('矩阵:修行合成因子', () => { it.each([ ['悟性低', 2], ['悟性中', 6], ['悟性高', 10] ] as const)('%s:感知因子单调', (label, perception) => { const w = mk(`rs-${label}`) const c = Object.values(w.state.members)[0]! c.perception = perception c.realm = { major: 'qi', minor: 1 } const rate = monthlyRate(w, c, 1) expect(rate).toBeGreaterThan(0) }) it.each([ ['闭关', 'meditation'], ['务农', 'farmer'], ['养伤', 'wounded'], ['探索', 'expedition'] ] as const)('状态 %s:速率成比例变化不崩', (label, state) => { const w = mk(`stt-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: 'qi', minor: 1 } c.state = state as never const rate = monthlyRate(w, c, 1) expect(rate).toBeGreaterThan(0) void rate }) it.each([ ['2岁', 2], ['7岁', 7], ['14岁', 14], ['70岁', 70], ['100岁', 100] ] as const)('年龄 %s:未成年/衰老年折价存在', (label, age) => { const w = mk(`ag-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: 'qi', minor: 1 } c.bornYear = w.state.year - age const rate = monthlyRate(w, c, 1) expect(rate).toBeGreaterThan(0) }) it.each([ ['无草', 0.6], ['半草', 0.8], ['足草', 1] ] as const)('herbFactor %s:无草衰减后不归零', (label, factor) => { const w = mk(`hf-${label}`) const c = Object.values(w.state.members)[0]! c.realm = { major: 'qi', minor: 2 } const rate = monthlyRate(w, c, factor) expect(rate).toBeGreaterThan(0) }) }) describe('矩阵:炼丹/铸器与库存', () => { it.each([ ['草足核缺', 100, 0], ['核足草缺', 0, 10], ['双足', 100, 10], ['双缺', 0, 0] ] as const)('craftPill %s:材料校验成立', (label, lingcao, beastcore) => { const w = mk(`cp-${label}`) w.state.family.buildings = { danfang: 1 } const fam = w.state.family fam.inventory['lingcao'] = lingcao fam.inventory['beastcore'] = beastcore fam.inventory['pill-qiyuan'] = 0 fam.stones = 500 const ok = w.craftPill('qiyuan') if (lingcao < 15) expect(ok).toBe(false) else expect(typeof ok).toBe('boolean') }) it.each([ ['单件', 1], ['十件', 10], ['零件', 0] ] as const)('forge %s:产出计数增量正确', (label, n) => { const w = mk(`fg-${label}`) const fam = w.state.family fam.inventory['lingkuang'] = 1000 fam.inventory['beastcore'] = 100 fam.stones = 100000 for (let i = 0; i < n; i++) w.forgeArtifact('weapon-qi') expect(fam.inventory['weapon-qi'] ?? 0).toBe(n) }) })