From 1724ce6b659850907d3bf5dc4daff70137804cf2 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 22 Sep 2026 04:37:59 +0800 Subject: feat(mapgen): 512x384 尺寸自适应参数与扩程回归(P23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - paramsForSize:河道数量随高度约每 96 行一条(64x48/256x192 仍 2 条,512x384 得 4 条), 第 3 条起在核心上/下方逐层外扩,互不重叠且不压核心。 - 噪声特征尺度封顶 4x,避免 512x384 退化成过度平滑的放大图。 - 64x48/256x192 生成结果逐字节不变(新增 checksum 锁定用例)。 - 新增 512x384 同 seed 逐字节一致/异 seed 分化/四河道连续/30 spawn 与桥两岸可达用例。 - Desktop 测试 124 -> 130。 --- src/LivingVillage.Desktop.Tests/MapGenTests.fs | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/MapGenTests.fs b/src/LivingVillage.Desktop.Tests/MapGenTests.fs index 4079ad0..4d11dd1 100644 --- a/src/LivingVillage.Desktop.Tests/MapGenTests.fs +++ b/src/LivingVillage.Desktop.Tests/MapGenTests.fs @@ -172,6 +172,69 @@ type MapGenTests () = 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") + // ---- P23:512x384 扩程(尺寸自适应参数 + 连续性/可达性 + 默认图锁定) ---- + + [] + member _.SizeAdaptiveParamsScaleRiversWithHeight () = + Assert.AreEqual(2, (MapGen.paramsForSize 64 48 (uint64 1)).RiverCount) + Assert.AreEqual(2, (MapGen.paramsForSize 256 192 (uint64 1)).RiverCount) + Assert.AreEqual(4, (MapGen.paramsForSize 512 384 (uint64 1)).RiverCount) + + [] + member _.HugeMap512SameSeedIsByteIdentical () = + let a = MapGen.generateWithSize 512 384 (uint64 4242) + let b = MapGen.generateWithSize 512 384 (uint64 4242) + tilesEqual a b "512x384 same seed" + Assert.AreEqual(MapGen.serialize a, MapGen.serialize b) + Assert.AreEqual(512, a.Width) + Assert.AreEqual(384, a.Height) + Assert.AreEqual(30, a.Spawns.Length) + Assert.IsTrue(a.ReachabilityOk, "512x384 must keep the core reachable") + Assert.IsTrue(a.BridgeCrossingsOk, "512x384 bridges must connect both banks") + + [] + member _.HugeMap512DifferentSeedsDiverge () = + let a = MapGen.generateWithSize 512 384 (uint64 4242) + let b = MapGen.generateWithSize 512 384 (uint64 7) + Assert.AreNotEqual(checksum a, checksum b, "different seeds must differ at 512x384") + Assert.AreNotEqual(MapGen.serialize a, MapGen.serialize b) + + [] + member _.HugeMap512RiversStayContinuousAcrossAllBands () = + let map = MapGen.generateWithSize 512 384 (uint64 4242) + Assert.AreEqual(4, map.Rivers.Length) + let minWidth = map.Rivers |> List.map (fun river -> river.Width) |> List.min + Assert.IsTrue(minWidth >= 3, "river width lower bound holds at 512x384") + for x in 1 .. map.Width - 2 do + let runs = waterRunsInColumn map x + if runs.Length <> map.Rivers.Length then + Assert.Fail(sprintf "column %d must hold exactly %d contiguous runs, saw %d" x map.Rivers.Length runs.Length) + for run in runs do + Assert.IsTrue(run >= minWidth, sprintf "column %d has a run of %d < min width %d" x run minWidth) + for y in 0 .. map.Height - 1 do + for x in 0 .. map.Width - 1 do + if map.Tiles.[y * map.Width + x] = int MapGen.GroundTile.Water then + Assert.IsTrue(waterNeighbourCount map x y >= 2, sprintf "water tile (%d,%d) is isolated" x y) + + [] + member _.HugeMap512ThirtySpawnsReachCoreAndBothBanks () = + let map = MapGen.generateWithSize 512 384 (uint64 4242) + let startX, startY = map.Spawns.Head + let visited = MapGen.floodFill map startX startY + for (x, y) in map.Spawns do + Assert.IsTrue(visited.[y * map.Width + x], sprintf "spawn (%d,%d) unreachable at 512x384" x y) + for building in map.Buildings do + Assert.IsTrue(visited.[building.DoorY * map.Width + building.DoorX], "building door unreachable at 512x384") + for (x, y) in map.Bridges do + Assert.IsTrue(visited.[y * map.Width + x], sprintf "bridge tile (%d,%d) unreachable at 512x384" x y) + Assert.IsTrue(map.Buildings.Length >= map.Rivers.Length, "riverside building per band at 512x384") + + /// 锁定当前默认尺寸的生成结果,防止 P23 参数适配无意改变 64x48 / 256x192。 + [] + member _.DefaultSizeChecksumsArePinned () = + Assert.AreEqual(6042052L, checksum (MapGen.generateWithSize 64 48 (uint64 4242))) + Assert.AreEqual(1284656962L, checksum (MapGen.generateWithSize 256 192 (uint64 4242))) + [] member _.VisibleRangeClampsAtLegacyMapEdges () = let x0, y0, x1, y1 = MapGen.visibleTileRange 64 48 0 0 2048 1536 -- cgit v1.2.3