summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel.Tests/M6aTests.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Kernel.Tests/M6aTests.fs')
-rw-r--r--src/LivingVillage.Kernel.Tests/M6aTests.fs99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/LivingVillage.Kernel.Tests/M6aTests.fs b/src/LivingVillage.Kernel.Tests/M6aTests.fs
new file mode 100644
index 0000000..8a318be
--- /dev/null
+++ b/src/LivingVillage.Kernel.Tests/M6aTests.fs
@@ -0,0 +1,99 @@
+namespace LivingVillage.Kernel.Tests
+
+open Microsoft.VisualStudio.TestTools.UnitTesting
+open LivingVillage.Kernel
+open LivingVillage.Kernel.Sim
+
+module private M6aHarness =
+
+ let zeroInput = { Input = { MoveX = 0.0f; MoveY = 0.0f } }
+
+ let atNpc (id: int) (world: World) : World =
+ let npc = world.Npcs.[id]
+ { world with Avatar = { world.Avatar with Pos = npc.Pos } }
+
+ let readyForChat (world: World) : World =
+ { world with
+ Npcs =
+ world.Npcs
+ |> Array.map (fun npc ->
+ { npc with
+ Mind =
+ { npc.Mind with
+ Action = Wander
+ Target = actionTarget Wander
+ ActionAge = minActionTicks
+ EffectDone = true } }) }
+
+ let withDialogue (world: World) : World =
+ match Sim.chooseDialogue (NpcId 0) SmallTalk (atNpc 0 world) with
+ | DialogueSucceeded (_, next) -> next
+ | DialogueRejected (failure, _) -> Assert.Fail($"dialogue rejected: {failure}"); Unchecked.defaultof<World>
+
+ let withChat (world: World) : World =
+ match Sim.chat { Narrator = NpcId 0; Receiver = NpcId 1 } (readyForChat world) with
+ | ChatSucceeded (Some _, next) -> next
+ | ChatSucceeded (None, _) -> Assert.Fail("chat should create a rumor"); Unchecked.defaultof<World>
+ | ChatRejected (failure, _) -> Assert.Fail($"chat rejected: {failure}"); Unchecked.defaultof<World>
+
+ let withTrade (world: World) : World =
+ match Sim.trade { Buyer = NpcId 0; Seller = NpcId 1; Item = Food; Quantity = 1 } world with
+ | TradeSucceeded next -> next
+ | TradeRejected (failure, _) -> Assert.Fail($"trade rejected: {failure}"); Unchecked.defaultof<World>
+
+ let advance (inputs: Input list) (world: World) : World =
+ inputs |> List.fold (fun current input -> Sim.step { Input = input } current) world
+
+[<TestClass>]
+type M6aTests () =
+
+ [<TestMethod>]
+ member _.SaveLoadPreservesWorldAndDeterministicContinuation () =
+ let world =
+ Sim.initialWorldN 7UL 4
+ |> M6aHarness.withDialogue
+ |> M6aHarness.withChat
+ |> M6aHarness.withTrade
+ let encoded = WorldSave.save world
+
+ match WorldSave.load encoded with
+ | Error failure -> Assert.Fail($"save should load: {failure}")
+ | Ok restored ->
+ Assert.AreEqual<string>(encoded, WorldSave.save restored)
+ let inputs =
+ [ { MoveX = 0.5f; MoveY = -0.25f }
+ { MoveX = 0.0f; MoveY = 0.0f }
+ { MoveX = -1.0f; MoveY = 0.75f }
+ { MoveX = 0.25f; MoveY = 0.0f } ]
+ let continued = M6aHarness.advance inputs world
+ let restoredContinued = M6aHarness.advance inputs restored
+ Assert.AreEqual<string>(WorldSave.save continued, WorldSave.save restoredContinued)
+ Assert.AreEqual<int64>(world.Tick, restored.Tick)
+ Assert.AreEqual<uint64>(world.Rng.State, restored.Rng.State)
+ Assert.IsFalse(restored.Events.IsEmpty)
+ Assert.IsFalse(restored.Rumors.IsEmpty)
+ Assert.IsFalse(restored.Annals.IsEmpty)
+ Assert.AreEqual<Avatar>(world.Avatar, restored.Avatar)
+ CollectionAssert.AreEqual(world.Npcs, restored.Npcs)
+
+ [<TestMethod>]
+ member _.SimulationClockSupportsPauseAndRequestedSpeeds () =
+ let initial = SimulationControl.initial
+ Assert.AreEqual<int>(1, SimulationControl.stepsPerFrame initial)
+ Assert.AreEqual<int>(2, SimulationControl.stepsPerFrame (SimulationControl.setSpeed TwoX initial))
+ Assert.AreEqual<int>(5, SimulationControl.stepsPerFrame (SimulationControl.setSpeed FiveX initial))
+ let paused = SimulationControl.togglePause initial
+ Assert.IsTrue(paused.Paused)
+ Assert.AreEqual<int>(0, SimulationControl.stepsPerFrame paused)
+ let resumed = SimulationControl.togglePause paused
+ Assert.IsFalse(resumed.Paused)
+ Assert.AreEqual<SimulationSpeed>(OneX, resumed.Speed)
+
+ [<TestMethod>]
+ member _.ConfiguredLegacyStepCountsRemainExactUntilManualSpeedSelection () =
+ let control, legacySteps = SimulationControl.initialForConfiguredSteps 7
+ Assert.AreEqual<int option>(Some 7, legacySteps)
+ Assert.AreEqual<int>(7, SimulationControl.stepsPerFrameWithLegacy legacySteps control)
+ Assert.AreEqual<int>(0, SimulationControl.stepsPerFrameWithLegacy legacySteps (SimulationControl.togglePause control))
+ let manuallySelected = SimulationControl.setSpeed TwoX control
+ Assert.AreEqual<int>(2, SimulationControl.stepsPerFrameWithLegacy None manuallySelected)