From 135aaa4c8a48522342fdae0c5e90e23ffec30d9a Mon Sep 17 00:00:00 2001 From: autocommit Date: Mon, 18 May 2026 20:10:30 -0700 Subject: [PATCH] =?UTF-8?q?feat(ai-ai):=20=E2=9C=A8=20Implement=20vision-a?= =?UTF-8?q?ware=20tactical=20projection=20with=20real-time=20environmental?= =?UTF-8?q?=20perception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- src/simulator/api-gdext/src/ai.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/simulator/api-gdext/src/ai.rs b/src/simulator/api-gdext/src/ai.rs index 9e0878b0..3d319b1d 100644 --- a/src/simulator/api-gdext/src/ai.rs +++ b/src/simulator/api-gdext/src/ai.rs @@ -30,7 +30,7 @@ use mc_ai::tactical::{ decide_tactical_actions, run_ai_turn, Action, TacticalEphemerals, TacticalMap, TacticalState, TacticalTile, }; -use mc_player_api::project_tactical; +use mc_player_api::project_tactical_with_vision; use mc_turn::GameState; // ── GdMcTreeController ─────────────────────────────────────────────────────── @@ -257,7 +257,15 @@ fn decide_strategic_kind(state: &GameState, player_index: usize, seed: u64) -> & .get(player_index) .map(|p| p.scoring_weights.clone()) .unwrap_or_default(); - let mut tactical = project_tactical(state, player_slot); + // p1-60 AI fairness: filter the projection through the active + // player's vision so the AI sees the same fog the human does. + let vision_state = mc_vision::compute_vision( + state, + &mc_vision::VisionCatalog::default(), + None, + ); + let pv = vision_state.for_player(player_slot); + let mut tactical = project_tactical_with_vision(state, player_slot, pv); // `run_ai_turn` debug-asserts state.current_player == player; the projector // sets current_player from the GameState's turn-order, not from the caller's // explicit slot, so align it here.