diff --git a/src/simulator/crates/mc-player-api/src/projection.rs b/src/simulator/crates/mc-player-api/src/projection.rs index b7d38f63..9417aa94 100644 --- a/src/simulator/crates/mc-player-api/src/projection.rs +++ b/src/simulator/crates/mc-player-api/src/projection.rs @@ -1169,10 +1169,14 @@ fn project_tactical_player( hex: (u.col, u.row), hp: u.hp.max(0) as u32, hp_max: u.max_hp.max(0) as u32, - // Bench `MapUnit` doesn't model moves_left — the turn processor - // refreshes it implicitly. v1 reports full (= 2) so the AI - // can plan a single move per turn. - moves_left: 2, + // Real remaining movement so the AI's world-model matches the + // dispatch's enforcement. Hardcoding 2 made the controller plan + // moves for already-exhausted units, so ~99% of its move + // suggestions were rejected "no movement points remaining" and + // armies barely maneuvered. `MapUnit::movement_remaining` is the + // same field the move dispatch decrements and the player view + // gates legal moves on (projection.rs ~444). + moves_left: u.movement_remaining.max(0) as u32, fortified: u.is_fortified, // p2-71b — flip the founder flag for the canonical Game-1 // founder so `TacticalUnit::is_founder()` returns true and the @@ -1377,6 +1381,7 @@ mod tests { u.unit_id = "dwarf_warrior".into(); u.hp = 100; u.max_hp = 100; + u.movement_remaining = 2; ps.units.push(u); } } else {