Add guard behavior for opening defenders

This commit is contained in:
2026-06-19 19:06:50 +09:00
parent f13f20939f
commit 8f1b6fb398
6 changed files with 232 additions and 3 deletions

View File

@@ -14,6 +14,7 @@ func _init() -> void:
_check_priority_action(state, failures)
_check_priority_changes_enemy_targeting(state, failures)
_check_reinforcement_priority_events(failures)
_check_guard_ai_behavior(failures)
if failures.is_empty():
print("event ai priority smoke ok")
@@ -90,6 +91,45 @@ func _check_reinforcement_priority_events(failures: Array[String]) -> void:
failures.append("Turn 7 reinforcement priority feedback missing")
func _check_guard_ai_behavior(failures: Array[String]) -> void:
var state = BattleStateScript.new()
if not state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("Could not load stage 1 guard AI scenario")
return
var guard: Dictionary = state.get_unit("yellow_turban_7")
if str(guard.get("ai_behavior", "")) != "guard":
failures.append("castle defender should load guard AI behavior")
if guard.get("ai_guard_anchor", Vector2i(-1, -1)) != Vector2i(19, 2):
failures.append("castle defender should keep its guard anchor: %s" % str(guard.get("ai_guard_anchor", null)))
if int(guard.get("ai_guard_radius", 0)) != 3:
failures.append("castle defender should keep its guard radius")
var movement_cells: Array[Vector2i] = state._ai_guard_movement_cells(guard, state._movement_range_for_unit(guard))
if state._ai_guard_is_engaged(guard, movement_cells):
failures.append("guard should not engage distant opening player positions")
state._enemy_take_action(guard)
if guard.get("pos", Vector2i.ZERO) != Vector2i(19, 2):
failures.append("guard should hold position instead of chasing distant targets: %s" % str(guard.get("pos", null)))
guard["pos"] = Vector2i(15, 2)
var displaced_return := state._best_ai_guard_return_cell(guard, state._ai_guard_movement_cells(guard, state._movement_range_for_unit(guard)))
if state._manhattan(displaced_return, Vector2i(19, 2)) >= state._manhattan(guard["pos"], Vector2i(19, 2)):
failures.append("displaced guard should choose a cell closer to its anchor: %s" % str(displaced_return))
state._enemy_take_action(guard)
if state._manhattan(guard.get("pos", Vector2i.ZERO), Vector2i(19, 2)) >= 4:
failures.append("displaced guard should step back toward its anchor: %s" % str(guard.get("pos", null)))
guard["pos"] = Vector2i(19, 2)
state.get_unit("cao_cao")["pos"] = Vector2i(18, 2)
movement_cells = state._ai_guard_movement_cells(guard, state._movement_range_for_unit(guard))
if not state._ai_guard_is_engaged(guard, movement_cells):
failures.append("guard should engage a player unit inside its guard radius")
var target: Dictionary = state._find_nearest_ai_guard_target(guard, "player")
if str(target.get("id", "")) != "cao_cao":
failures.append("guard target search should prefer targets inside the guard zone: %s" % str(target.get("id", "")))
func _feedback_has(feedback: Array[Dictionary], expected_unit_id: String, expected_text: String, expected_kind: String) -> bool:
for entry in feedback:
if (