1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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)
|