From 623ee728e939663aa4c98a731dcd0dcfe58bdb90 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 11:08:58 +0800 Subject: feat(desktop): 江南水乡河道横贯与波纹两帧 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 场景改为沿村蜿蜒水带(北岸凸湾、中段横贯、南段收窄),南北两岸石板路沿河展开,木桥三块纵跨全河连接民居门前石径;水面新增第二张波纹图块,按世界 tick/32 取模确定性交替,绘制无新增每帧分配。 --- src/LivingVillage.Desktop.Tests/PrototypeTests.fs | 38 +++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs index 06b3250..7959d27 100644 --- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs +++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs @@ -301,8 +301,42 @@ type PrototypeTests () = Assert.IsTrue(footprint.Contains({ X = door.X + dx; Y = door.Y - 2 } : TilePosition), sprintf "missing ridge tile dx=%d" dx) Assert.IsTrue(footprint.Contains({ X = door.X + dx; Y = door.Y - 1 } : TilePosition), sprintf "missing eave tile dx=%d" dx) Assert.IsTrue(footprint.Contains({ X = door.X + dx; Y = door.Y } : TilePosition), sprintf "missing wall tile dx=%d" dx) - // 12 house tiles + 2 bridge + 3 bamboo + 2 garden. - Assert.AreEqual(19, footprint.Count) + // 12 house tiles + 3 bridge + 3 bamboo + 2 garden. + Assert.AreEqual(20, footprint.Count) + + [] + member _.WaterRippleFramesAreDeterministicAndTwoPhase () = + Assert.AreEqual(0, VillageArt.waterFrameTick 0L) + Assert.AreEqual(0, VillageArt.waterFrameTick 31L) + Assert.AreEqual(1, VillageArt.waterFrameTick 32L) + Assert.AreEqual(1, VillageArt.waterFrameTick 63L) + Assert.AreEqual(0, VillageArt.waterFrameTick 64L) + Assert.AreEqual(VillageArt.waterFrameTick 100L, VillageArt.waterFrameTick 100L) + + [] + member _.RiverBandSpansTheSceneWithBankPathsAndCrossing () = + let plan = VillageArt.sampleRenderPlan () + let footprintOf (value: VillageArt.JiangnanRenderPlan) = VillageArt.planFootprint value + let waters = plan.Grounds |> List.filter (fun (_, kind) -> kind = VillageArt.Water) |> List.map fst |> Set.ofList + let paths = plan.Grounds |> List.filter (fun (_, kind) -> kind = VillageArt.StonePath) |> List.map fst |> Set.ofList + let door = scene.Homes |> List.head |> fun home -> home.Door + + // The river must run the full width of the decorated scene as a readable water band. + Assert.AreEqual(20, [ 0 .. 19 ] |> List.filter (fun x -> waters.Contains({ X = x; Y = 12 } : TilePosition)) |> List.length) + Assert.IsTrue(waters.Contains({ X = 6; Y = 13 } : TilePosition)) + // Banks stay walkable stone, and the door row connects to the north bank. + for x in 0 .. 19 do + if x <> 6 && x <> 7 && x <> 8 then + Assert.IsTrue(paths.Contains({ X = x; Y = 11 } : TilePosition), sprintf "missing north bank x=%d" x) + for y in 6 .. 10 do + Assert.IsTrue(paths.Contains({ X = 6; Y = y } : TilePosition), sprintf "missing door connector y=%d" y) + // Bridge footprint crosses the full river between the banks. + let bridge = plan.Props |> List.find (fun prop -> prop.Kind = VillageArt.Bridge) + let expectedBridge : TilePosition = { X = 6; Y = 11 } + Assert.AreEqual(expectedBridge, bridge.Position) + for y in 11 .. 13 do + let bridgeTile = VillageArt.worldTile plan { X = 6; Y = y } + Assert.IsTrue(footprintOf plan |> List.contains bridgeTile, sprintf "bridge tile y=%d" y) [] member _.FacingUsesTheActualMovementOrTargetVector () = -- cgit v1.2.3