diff --git a/src/game/engine/tests/unit/test_pathfinder_embark.gd b/src/game/engine/tests/unit/test_pathfinder_embark.gd new file mode 100644 index 00000000..c7e1ae49 --- /dev/null +++ b/src/game/engine/tests/unit/test_pathfinder_embark.gd @@ -0,0 +1,53 @@ +extends GutTest +## p3-18 — the rendered pathfinder (`pathfinder.gd`) lets a land unit enter water +## only when its owner can embark (`embark_level > 0`). The embark level itself is +## computed in Rust (`GdTechWeb.embark_level`, data-driven from tech mechanics); +## this verifies the thin GDScript gate consumes it so UI movement matches the +## authoritative headless sim's embark rule. + +const GameMapScript: GDScript = preload("res://engine/src/map/game_map.gd") +const TileScript: GDScript = preload("res://engine/src/map/tile.gd") +const PathfinderScript: GDScript = preload("res://engine/src/map/pathfinder.gd") + + +## A vertical ocean wall: col 0 land | col 1 ocean (all rows) | col 2 land. Any +## path from col 0 to col 2 must cross the ocean column. +func _ocean_wall_map() -> GameMap: + var m: GameMap = GameMapScript.new() + m.initialize(3, 3, 0) # WrapMode.NONE + for q: int in range(3): + for r: int in range(3): + var t: Tile = TileScript.new() + t.position = Vector2i(q, r) + t.biome_id = "ocean" if q == 1 else "plains" + m.tiles[Vector2i(q, r)] = t + return m + + +func test_land_unit_blocked_by_water_without_embark() -> void: + var m: GameMap = _ocean_wall_map() + var path: Array[Vector2i] = PathfinderScript.find_path( + m, Vector2i(0, 0), Vector2i(2, 0), 20, "land", 0 + ) + assert_eq(path.size(), 0, "no embark → the ocean column blocks the land unit") + + +func test_land_unit_crosses_water_with_embark() -> void: + var m: GameMap = _ocean_wall_map() + var path: Array[Vector2i] = PathfinderScript.find_path( + m, Vector2i(0, 0), Vector2i(2, 0), 20, "land", 1 + ) + assert_gt(path.size(), 0, "embark_level > 0 → land unit fords the ocean column") + assert_eq( + path[path.size() - 1], Vector2i(2, 0), "embarked land unit reaches the far landmass" + ) + + +func test_naval_unit_ignores_embark_level() -> void: + # Naval movement is unchanged by the embark arg (it always needs water). + var m: GameMap = _ocean_wall_map() + # A naval unit can sit on / traverse the ocean column regardless of embark. + var on_water: Array[Vector2i] = PathfinderScript.find_path( + m, Vector2i(1, 0), Vector2i(1, 2), 20, "naval", 0 + ) + assert_gt(on_water.size(), 0, "naval unit traverses water with embark_level 0")