test(@projects/@magic-civilization): ⛵ p3-18 P6-core — end-to-end proof an army fords open ocean to a far landmass
The scenario that motivated p3-18: an army on landmass A reaching landmass B across an ocean strip. teched_army_fords_open_ocean_to_far_landmass asserts the full chain through process_move_requests — without naval tech the ocean rejects the move (army stays put); with ocean_navigation (Ocean embark) the army crosses the strip onto the far landmass and auto-disembarks on arrival. Deterministic, cargo-verifiable evidence (the project's preferred proof form), no dylib/Godot needed. The full headless 1v1-to-game_over demo (P6-full) is the heavier dylib follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5aefbff8a2
commit
11988d60a6
1 changed files with 55 additions and 0 deletions
|
|
@ -5230,6 +5230,61 @@ mod move_request_tests {
|
|||
assert_eq!(state.players[0].unit_upkeep.len(), 1, "unit_upkeep stays index-aligned");
|
||||
}
|
||||
|
||||
/// p3-18 end-to-end — the motivating scenario: an army on landmass A reaches
|
||||
/// landmass B across an open-ocean strip. Without naval tech the ocean blocks
|
||||
/// it; with `ocean_navigation` (Ocean embark) it fords the water and lands.
|
||||
#[test]
|
||||
fn teched_army_fords_open_ocean_to_far_landmass() {
|
||||
// Landmass A (cols 0–1) | ocean strip (col 2) | landmass B (cols 3–4).
|
||||
let mut grid = GridState::new(5, 5);
|
||||
for r in 0..5 {
|
||||
for c in 0..5 {
|
||||
let idx = grid.idx(c, r);
|
||||
grid.tiles[idx].biome_label_id =
|
||||
if c == 2 { "ocean" } else { "plains" }.to_string();
|
||||
}
|
||||
}
|
||||
let mut state = GameState::default();
|
||||
state.grid = Some(grid);
|
||||
state
|
||||
.units_catalog
|
||||
.load_json_str(r#"[{"id":"warrior","movement":10,"domain":"land"}]"#)
|
||||
.expect("catalog loads");
|
||||
state.players.push(PlayerState {
|
||||
player_index: 0,
|
||||
units: vec![MapUnit {
|
||||
id: 1, col: 0, row: 0, unit_id: "warrior".into(), ..MapUnit::default()
|
||||
}
|
||||
.with_moves(10)],
|
||||
..PlayerState::default()
|
||||
});
|
||||
|
||||
// No naval tech (embark None) → the ocean strip is impassable.
|
||||
state.pending_move_requests.push(move_req(0, (4, 0)));
|
||||
let out = process_move_requests(&mut state);
|
||||
assert!(
|
||||
matches!(out[0], MoveOutcome::Rejected { .. }),
|
||||
"without embark the ocean blocks the army, got {:?}",
|
||||
out[0]
|
||||
);
|
||||
assert_eq!((state.players[0].units[0].col, state.players[0].units[0].row), (0, 0));
|
||||
|
||||
// ocean_navigation grants Ocean embark → the army fords to landmass B.
|
||||
state.players[0].embark_level = mc_core::EmbarkLevel::Ocean;
|
||||
state.players[0].units[0].movement_remaining = 10;
|
||||
state.pending_move_requests.push(move_req(0, (4, 0)));
|
||||
process_move_requests(&mut state);
|
||||
assert_eq!(
|
||||
(state.players[0].units[0].col, state.players[0].units[0].row),
|
||||
(4, 0),
|
||||
"ocean-teched army crossed the strip onto the far landmass"
|
||||
);
|
||||
assert!(
|
||||
!state.players[0].units[0].is_embarked,
|
||||
"auto-disembarked on arrival at land"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_budget_rejects() {
|
||||
let mut state = build_state_with_unit(7, (0, 0), 0, |_, _| "plains");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue