feat(@projects/@magic-civilization): ✨ add authoritative turn step without inline movement
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
8dcab6df6e
commit
66d0a8ecab
2 changed files with 32 additions and 7 deletions
|
|
@ -412,7 +412,12 @@ fn apply_end_turn(state: &mut GameState, player: PlayerId) -> Result<Vec<Event>,
|
|||
if let Some(vc) = victory_config_from_env() {
|
||||
processor.victory_config = Some(vc);
|
||||
}
|
||||
let mut result = processor.step(state);
|
||||
// Authoritative path: units were already moved by the real tactical AI
|
||||
// (`drive_ai_slot` → `run_ai_turn`) earlier in this `apply_end_turn`, so we
|
||||
// run the turn WITHOUT mc-turn's inline bench-grade movement heuristic —
|
||||
// otherwise the dumb nearest-enemy/lair seek re-moves what the real AI
|
||||
// positioned. `step_authoritative` runs the full turn minus Phase-5 movement.
|
||||
let mut result = processor.step_authoritative(state);
|
||||
// Communications Phase 6 — end-of-turn comms passes.
|
||||
// Runs after the processor step (so `state.turn` is the new turn
|
||||
// and `step_comms` evaluates deliveries against it). Order:
|
||||
|
|
|
|||
|
|
@ -386,10 +386,29 @@ impl TurnProcessor {
|
|||
self.culture_web_parsed.as_ref()
|
||||
}
|
||||
|
||||
/// Advance `state` by one turn. Deterministic: same state in → same state
|
||||
/// out (the processor uses a hash-mixed deterministic RNG derived from
|
||||
/// `state.turn`).
|
||||
/// Advance `state` by one turn with the **inline bench-grade movement AI**
|
||||
/// (Phase-5 nearest enemy/city/lair seek). Used by the headless self-play
|
||||
/// benches (`dominion_bench`, `solo_dominion`, …) where the inline heuristic
|
||||
/// is the only mover. Deterministic: same state in → same state out.
|
||||
pub fn step(&self, state: &mut GameState) -> TurnResult {
|
||||
self.step_impl(state, true)
|
||||
}
|
||||
|
||||
/// Advance `state` by one turn WITHOUT the inline movement AI — the
|
||||
/// **authoritative** path. Movement is owned by the real tactical AI
|
||||
/// (`mc_ai::tactical::run_ai_turn`, applied via
|
||||
/// `mc_player_api::dispatch::drive_ai_slot` *before* this call), so the
|
||||
/// inline nearest-enemy/lair heuristic must NOT re-move what the real AI
|
||||
/// positioned. Runs the full turn (economy / production / culture / combat /
|
||||
/// victory) exactly like [`step`], skipping only the Phase-5 movement loop.
|
||||
pub fn step_authoritative(&self, state: &mut GameState) -> TurnResult {
|
||||
self.step_impl(state, false)
|
||||
}
|
||||
|
||||
/// Shared turn body. `move_units` gates the Phase-5 inline movement loop
|
||||
/// (see [`process_fauna_encounters_inner`]). Deterministic: same state +
|
||||
/// same `move_units` in → same state out (hash-mixed RNG from `state.turn`).
|
||||
fn step_impl(&self, state: &mut GameState, move_units: bool) -> TurnResult {
|
||||
state.turn += 1;
|
||||
let mut result = TurnResult::default();
|
||||
|
||||
|
|
@ -486,9 +505,10 @@ impl TurnProcessor {
|
|||
self.process_escort_requests(state);
|
||||
|
||||
// Phase 5a: movement + fauna encounters.
|
||||
// Movement runs unconditionally; fauna encounters only fire
|
||||
// when a grid with lairs exists.
|
||||
self.process_fauna_encounters_inner(state, &mut result, true);
|
||||
// Movement runs only when `move_units` (bench path); the authoritative
|
||||
// path drives movement via run_ai_turn before the turn and passes false.
|
||||
// Fauna encounters fire whenever a grid with lairs exists.
|
||||
self.process_fauna_encounters_inner(state, &mut result, move_units);
|
||||
|
||||
// Phase 5a-sentry: wake sentrying units that have enemies in vision range (2 hex).
|
||||
// Runs after movement so positions are current; runs before PvP so the
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue