From f561ec4cc9eda5e7dddd35703e56bd250211c899 Mon Sep 17 00:00:00 2001 From: autocommit Date: Wed, 29 Apr 2026 09:59:55 -0700 Subject: [PATCH] =?UTF-8?q?test(scenes):=20=E2=9C=85=20Add=20and=20update?= =?UTF-8?q?=20test=20logic=20in=20courier=5Fera2=5Fround=5Ftrip=5Fproof.gd?= =?UTF-8?q?=20and=20courier=5Fera2=5Fround=5Ftrip=5Fproof.tscn=20to=20veri?= =?UTF-8?q?fy=20round-trip=20behavior=20for=20courier=20era=202.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../tests/courier_era2_round_trip_proof.gd | 129 ++++++++++++++++++ .../tests/courier_era2_round_trip_proof.tscn | 6 + 2 files changed, 135 insertions(+) create mode 100644 src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd create mode 100644 src/game/engine/scenes/tests/courier_era2_round_trip_proof.tscn diff --git a/src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd b/src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd new file mode 100644 index 00000000..e9652b35 --- /dev/null +++ b/src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd @@ -0,0 +1,129 @@ +extends Node +## p3-01 bullet 11: era_2 courier round-trip proof. +## Signs a SharedMapAgreement between two players whose capitals are 4 hexes +## apart, dispatches an era_2 (foot_runner, 1 hex/turn) courier via straight- +## line movement, and steps turn-by-turn until SharedMapDelivered fires. +## Asserts delivery occurs within 6 steps and the share-window opens. + +var _pass_count: int = 0 +var _fail_count: int = 0 + + +func _ready() -> void: + if not ClassDB.class_exists("GdTradeLedger"): + print("[SKIP] GdTradeLedger not registered — GDExtension not loaded") + get_tree().quit(0) + return + _run_proof() + _print_results() + get_tree().quit(0 if _fail_count == 0 else 1) + + +func _run_proof() -> void: + # Build a GameState with two players whose capitals are 4 hexes apart. + var state: RefCounted = ClassDB.instantiate("GdGameState") as RefCounted + if not _assert("GdGameState instantiates", state != null): + return + state.call("create_grid", 10, 10) + state.call("add_player_militarist", 0, 0) # player 0 capital at (0,0) + state.call("add_player_militarist", 4, 0) # player 1 capital at (4,0) + + # Build the courier map view from that state. + var map_view_inst: RefCounted = ClassDB.instantiate("GdCourierMapView") as RefCounted + if not _assert("GdCourierMapView instantiates", map_view_inst != null): + return + # from_game_state is a static constructor; call it via instance in GDScript. + var gd_map_view: RefCounted = map_view_inst.call("from_game_state", state) as RefCounted + if not _assert("GdCourierMapView.from_game_state returns non-null", gd_map_view != null): + return + + var gd_trade: RefCounted = ClassDB.instantiate("GdTrade") as RefCounted + if not _assert("GdTrade instantiates", gd_trade != null): + return + + # Build a SharedMapAgreement and an era_2 courier route, add to ledger. + var sm: RefCounted = gd_trade.call("shared_map_agreement_new", 0, 1, 50, 6) as RefCounted + if not _assert("SharedMapAgreement created", sm != null): + return + + var route: RefCounted = gd_trade.call("courier_route_new", 0, 1) as RefCounted + if not _assert("CourierRoute created", route != null): + return + + # Build ledger JSON with the era_2 courier at position (0,0), no path + # (straight-line fallback moves 1 hex/turn toward (4,0)). + var ledger_inst: RefCounted = ClassDB.instantiate("GdTradeLedger") as RefCounted + if not _assert("GdTradeLedger instantiates", ledger_inst != null): + return + + var agreement_json: String = JSON.stringify({ + "agreements": [ + { + "SharedMap": { + "agreement_id": 0, + "partners": [0, 1], + "turn_started": 1, + "duration": 6, + "share_turns_remaining": 0, + "payment_gold": 50, + "payment_luxury": null, + "courier_route": { + "sender": 0, + "receiver": 1, + "courier_era_tier": 2, + "dispatched_turn": 1, + "position": [0, 0], + "eta_turn": null, + "delivered": false, + "intercepted": false, + "planned_path": [], + "path_step": 0 + } + } + } + ], + "next_agreement_id": 1 + }) + # from_json is a static factory; in GDScript call via instance. + var ledger: RefCounted = ledger_inst.call("from_json", agreement_json) as RefCounted + if not _assert("Ledger loads from JSON", ledger != null): + return + + # Step up to 20 turns; era_2 moves 1 hex/turn, 4 hexes → deliver by turn 4. + var delivered_event_found: bool = false + var delivered_turn: int = -1 + for turn: int in range(1, 21): + var events: Array = gd_trade.call("step_shared_map_agreements", ledger, gd_map_view, turn) as Array + for ev: Dictionary in events: + if ev.get("type") == "shared_map_delivered": + delivered_event_found = true + delivered_turn = turn + break + if delivered_event_found: + break + + _assert("SharedMapDelivered event emitted within 20 steps", delivered_event_found) + _assert("Delivery happens by turn 6 (4 hexes at 1/turn + slack)", delivered_turn <= 6) + + # After delivery the agreement should be in the share-window phase. + var sm_agreements: Array = ledger.call("iter_shared_map") as Array + _assert("Ledger contains SharedMap agreement after delivery", sm_agreements.size() == 1) + if sm_agreements.size() > 0: + var sm_out: RefCounted = sm_agreements[0] as RefCounted + _assert("Agreement is_delivered", sm_out.call("is_delivered") as bool) + var share_remaining: int = sm_out.call("get_share_turns_remaining") as int + _assert("Share window is open (turns_remaining > 0)", share_remaining > 0) + + +func _assert(label: String, condition: bool) -> bool: + if condition: + _pass_count += 1 + print("[PASS] %s" % label) + else: + _fail_count += 1 + push_error("[FAIL] %s" % label) + return condition + + +func _print_results() -> void: + print("courier_era2_round_trip_proof: %d passed, %d failed" % [_pass_count, _fail_count]) diff --git a/src/game/engine/scenes/tests/courier_era2_round_trip_proof.tscn b/src/game/engine/scenes/tests/courier_era2_round_trip_proof.tscn new file mode 100644 index 00000000..42f3b0ba --- /dev/null +++ b/src/game/engine/scenes/tests/courier_era2_round_trip_proof.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://courier_era2_round_trip"] + +[ext_resource type="Script" path="res://engine/scenes/tests/courier_era2_round_trip_proof.gd" id="1"] + +[node name="CourierEra2RoundTripProof" type="Node"] +script = ExtResource("1")