summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop.Tests/MapGenTests.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 02:57:12 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 02:57:12 +0800
commitd06656aa968ccb2769ba7c90c97f57f2818bb828 (patch)
tree4b1d8422233517830e1081c70eff86e241483590 /src/LivingVillage.Desktop.Tests/MapGenTests.fs
parentd3c0ef17cb1c4d30c1d586e2a5b616f58bd3d875 (diff)
downloadliving-village-d06656aa968ccb2769ba7c90c97f57f2818bb828.tar.gz
feat(mapgen): 生成器序列化 + 世界站位接入(P20 第三步 A)
- MapGen.serialize:生成结果的确定性序列化(尺寸/seed/瓦片/Rivers/Bridges/ Paths/Buildings),同 seed 逐字节一致,供回归与跨机核对。 - WorldBootstrap.initialWorldWithPlacement:显式站位建世界;旧 64x48 路径 (initialWorld/initialWorldWithOccupation)字节口径不变。 - WorldBootstrap.initialWorldInMap:用生成器核心可达区做站位,30 spawn 全落 可达核心;新增 serialization/placement 两条测试。 - fsproj:MapGen 先于 WorldBootstrap 编译。 - Desktop 119->121,Kernel 90 不变。
Diffstat (limited to 'src/LivingVillage.Desktop.Tests/MapGenTests.fs')
-rw-r--r--src/LivingVillage.Desktop.Tests/MapGenTests.fs25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop.Tests/MapGenTests.fs b/src/LivingVillage.Desktop.Tests/MapGenTests.fs
index b0b58e7..4079ad0 100644
--- a/src/LivingVillage.Desktop.Tests/MapGenTests.fs
+++ b/src/LivingVillage.Desktop.Tests/MapGenTests.fs
@@ -147,6 +147,31 @@ type MapGenTests () =
let c = MapGen.generateWithSize 256 192 (uint64 7)
Assert.IsTrue(a.Buildings <> c.Buildings || a.Bridges <> c.Bridges, "different seeds must relocate structures")
+ // ---- P20 第三步:序列化确定性 + 默认可玩世界接入生成器站位 ----
+
+ [<TestMethod>]
+ member _.SameSeedSerializationIsByteIdentical () =
+ let a = MapGen.generateWithSize 256 192 (uint64 4242)
+ let b = MapGen.generateWithSize 256 192 (uint64 4242)
+ Assert.AreEqual<string>(MapGen.serialize a, MapGen.serialize b)
+ let c = MapGen.generateWithSize 256 192 (uint64 7)
+ Assert.AreNotEqual<string>(MapGen.serialize a, MapGen.serialize c)
+
+ [<TestMethod>]
+ member _.MapWorldPlacementUsesReachableCoreSpawns () =
+ let map = MapGen.generateWithSize 256 192 (uint64 4242)
+ let world = WorldBootstrap.initialWorldInMap false 42UL Sim.npcCount map
+ Assert.AreEqual<int>(Sim.npcCount, world.Npcs.Length)
+ let visited = MapGen.floodFill map (fst map.Spawns.Head) (snd map.Spawns.Head)
+ for npc in world.Npcs do
+ let tx = int npc.Pos.X / Sim.tilePixels
+ let ty = int npc.Pos.Y / Sim.tilePixels
+ Assert.IsTrue(visited.[ty * map.Width + tx], sprintf "npc tile (%d,%d) must be reachable from the core" tx ty)
+ let ax = int world.Avatar.Pos.X / Sim.tilePixels
+ let ay = int world.Avatar.Pos.Y / Sim.tilePixels
+ Assert.IsTrue(visited.[ay * map.Width + ax], "avatar spawn must sit in the reachable core")
+ Assert.IsTrue(ax >= map.Core.MinX && ax <= map.Core.MaxX && ay >= map.Core.MinY && ay <= map.Core.MaxY, "avatar spawn must sit in the core")
+
[<TestMethod>]
member _.VisibleRangeClampsAtLegacyMapEdges () =
let x0, y0, x1, y1 = MapGen.visibleTileRange 64 48 0 0 2048 1536