diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-19 02:24:26 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-19 02:24:26 +0800 |
| commit | 4627a29302aa780ba8de1e537a869650601debc3 (patch) | |
| tree | fe9639ce194298372bb59a80244698cbee7811c0 /src/LivingVillage.Kernel.Tests | |
| parent | 59458d149d7cecf73e708faa6d9e6db2bcd89dfd (diff) | |
| download | living-village-4627a29302aa780ba8de1e537a869650601debc3.tar.gz | |
feat: M2a NPC 心智基础 — Needs 衰减 + Personality(seed) + 决策层v1(需求缺口×性格权重) + 四语义点直线移动 + headless NPC 摘要 + 对拍/衰减测试
Diffstat (limited to 'src/LivingVillage.Kernel.Tests')
| -rw-r--r-- | src/LivingVillage.Kernel.Tests/DeterminismTests.fs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/LivingVillage.Kernel.Tests/DeterminismTests.fs b/src/LivingVillage.Kernel.Tests/DeterminismTests.fs index 2e2663b..aba794e 100644 --- a/src/LivingVillage.Kernel.Tests/DeterminismTests.fs +++ b/src/LivingVillage.Kernel.Tests/DeterminismTests.fs @@ -133,3 +133,50 @@ type DeterminismTests () = let f, rng' = Rng.nextFloat32 rng if f < 0.0f || f >= 1.0f then Assert.Fail($"out of range: {f}") rng <- rng' + + [<TestMethod>] + member _.NpcDecisionTraceIsTickByTickDeterministic () = + let runNpc (seed: uint64) (ticks: int64) : World list = + let mutable world = Sim.initialWorld seed + let acc = ResizeArray<World> (int ticks + 1) + acc.Add world + let zero = { Input = { MoveX = 0.0f; MoveY = 0.0f } } + for _ in 1L .. ticks do + world <- Sim.step zero world + acc.Add world + List.ofSeq acc + let a = runNpc 42UL 20000L + let b = runNpc 42UL 20000L + Assert.IsTrue(20001 = List.length a) + CollectionAssert.AreEqual(Array.ofList a, Array.ofList b) + + [<TestMethod>] + member _.NpcNeedsDecayOverTimeAndActionsDifferAcrossSeeds () = + let w0 = Sim.initialWorld 42UL + let npc0 = List.exactlyOne w0.Npcs + let zero = { Input = { MoveX = 0.0f; MoveY = 0.0f } } + let mutable w = w0 + for _ in 1 .. 500 do + w <- Sim.step zero w + let npc1 = List.exactlyOne w.Npcs + let n0 = npc0.Mind.Needs + let n1 = npc1.Mind.Needs + Assert.IsTrue(n1.Hunger < n0.Hunger, "hunger must decay") + Assert.IsTrue(n1.Energy < n0.Energy, "energy must decay") + Assert.IsTrue(n1.Social < n0.Social, "social must decay") + Assert.IsTrue(n1.Money < n0.Money, "money must decay") + let wa = Sim.initialWorld 42UL + let wb = Sim.initialWorld 43UL + Assert.IsTrue(wa.Npcs.[0].Mind.Personality <> wb.Npcs.[0].Mind.Personality, + "personalities must differ across seeds") + let mutable ta = wa + let mutable tb = wb + let seqA = ResizeArray<NpcActionKind> 20000 + let seqB = ResizeArray<NpcActionKind> 20000 + for _ in 1 .. 20000 do + ta <- Sim.step zero ta + tb <- Sim.step zero tb + seqA.Add ta.Npcs.[0].Mind.Action + seqB.Add tb.Npcs.[0].Mind.Action + if Seq.compareWith compare seqA seqB = 0 then + Assert.Fail("npc action sequence must diverge across seeds") |
