using Theriapolis.Core; using Theriapolis.Core.Entities; using Theriapolis.Core.World; using Xunit; namespace Theriapolis.Tests.Entities; public sealed class WorldTravelPlannerTests : IClassFixture { private const ulong TestSeed = 0xCAFEBABEUL; private readonly WorldCache _cache; public WorldTravelPlannerTests(WorldCache c) => _cache = c; [Fact] public void Plan_BetweenAdjacentSettlements_ReturnsConnectedPath() { var w = _cache.Get(TestSeed).World; var inhabited = w.Settlements.Where(s => !s.IsPoi && s.Tier <= 3).Take(2).ToArray(); Assert.Equal(2, inhabited.Length); var planner = new WorldTravelPlanner(w); var path = planner.PlanTilePath(inhabited[0].TileX, inhabited[0].TileY, inhabited[1].TileX, inhabited[1].TileY); Assert.NotNull(path); Assert.True(path!.Count >= 2); // Endpoints match the request. Assert.Equal((inhabited[0].TileX, inhabited[0].TileY), path[0]); Assert.Equal((inhabited[1].TileX, inhabited[1].TileY), path[^1]); // No teleporting — every adjacent pair is within Chebyshev 1. for (int i = 1; i < path.Count; i++) { int dx = Math.Abs(path[i].X - path[i - 1].X); int dy = Math.Abs(path[i].Y - path[i - 1].Y); Assert.True(dx <= 1 && dy <= 1); Assert.False(dx == 0 && dy == 0); } } [Fact] public void Plan_FromOcean_ReturnsNull() { var w = _cache.Get(TestSeed).World; // Find an ocean tile and a land tile. (int ox, int oy) = (-1, -1); for (int y = 0; y < C.WORLD_HEIGHT_TILES && oy < 0; y++) for (int x = 0; x < C.WORLD_WIDTH_TILES && oy < 0; x++) if (w.TileAt(x, y).Biome == BiomeId.Ocean) { ox = x; oy = y; } Assert.True(ox >= 0, "world should have at least one ocean tile"); var inhabited = w.Settlements.First(s => !s.IsPoi); var planner = new WorldTravelPlanner(w); var path = planner.PlanTilePath(ox, oy, inhabited.TileX, inhabited.TileY); Assert.Null(path); } }