Campaign tests: every mission runs a simulated minute undecided; missions 1 and 2 are won by a scripted player
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6c85a62f1b
commit
b8bf2b8503
1 file changed
+83
@@ -421,6 +421,89 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missions_run_and_are_not_decided_at_once() {
|
||||
for (i, d) in missions().iter().enumerate() {
|
||||
let mut g = start_mission(i, None);
|
||||
let m = g.mission.clone().unwrap();
|
||||
assert!(!m.goals.iter().all(|&goal| g.goal_done(goal)), "{}: goals done at the start", d.key);
|
||||
let t = std::time::Instant::now();
|
||||
for _ in 0..(60 * 20) {
|
||||
g.update(0.05);
|
||||
}
|
||||
println!("{}: 60 s simulated in {} ms, state {}, core {:.0}", d.key, t.elapsed().as_millis(), g.state, g.core_hp);
|
||||
assert_eq!(g.state, 0, "{}: decided without the player", d.key);
|
||||
}
|
||||
}
|
||||
|
||||
// A simple scripted player: digs a corridor to the shard, bridges rivers on the way and
|
||||
// sends a few strong creatures along with the flag.
|
||||
fn play_to_shard(i: usize) -> (u8, f32) {
|
||||
let mut g = start_mission(i, None);
|
||||
let (cx, cy) = g.map.core;
|
||||
let shard = g.map.t.iter().position(|t| t.kind == Kind::Shard).unwrap();
|
||||
let path = g
|
||||
.map
|
||||
.search(idx(cx + 1, cy - 2), |j| {
|
||||
let t = &g.map.t[j];
|
||||
match t.kind {
|
||||
Kind::Rock | Kind::Core | Kind::Tower => None,
|
||||
Kind::Water | Kind::Lava => Some(3),
|
||||
k if t.solid() => Some(if t.reinforced { 6 } else { 2 }),
|
||||
_ => Some(1),
|
||||
}
|
||||
}, |j| j == shard, false)
|
||||
.expect("a way to the shard");
|
||||
for &j in &path {
|
||||
if g.map.t[j].diggable() {
|
||||
g.map.t[j].marked = true;
|
||||
}
|
||||
}
|
||||
for k in [EK::Ogre, EK::Ogre, EK::Mage, EK::Ogre] {
|
||||
g.spawn(k, false, cx as f32 + 4.5, cy as f32 + 1.5, 4);
|
||||
}
|
||||
g.gold = 3000.0;
|
||||
// lair and mushroom garden at the sides of the start area
|
||||
g.build_rect(1, cx - 3, cy - 3, cx - 2, cy + 5);
|
||||
g.build_rect(2, cx + 4, cy - 3, cx + 5, cy + 5);
|
||||
g.gold = 2500.0; // as if the player had mined some gold
|
||||
let mut t = 0.0;
|
||||
while t < 1500.0 && g.state == 0 {
|
||||
for _ in 0..20 {
|
||||
g.update(0.05);
|
||||
}
|
||||
t += 1.0;
|
||||
// fallen imps are replaced
|
||||
if t as i32 % 10 == 0 && g.worker_count() < 4 {
|
||||
g.summon(cx as f32 + 1.5, cy as f32 - 1.5);
|
||||
}
|
||||
// bridges: every few seconds try to bridge the water on the path
|
||||
if t as i32 % 5 == 0 {
|
||||
for &j in &path {
|
||||
if g.map.t[j].liquid() {
|
||||
let (x, y) = xy(j);
|
||||
g.build_bridges(x, y, x, y);
|
||||
}
|
||||
}
|
||||
// the creatures follow the digging: flag at the furthest open tile of the path
|
||||
if let Some(&j) = path.iter().rev().find(|&&j| g.map.t[j].walkable()) {
|
||||
let (x, y) = xy(j);
|
||||
g.set_flag(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
(g.state, t)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first_missions_can_be_won() {
|
||||
for i in [0, 1] {
|
||||
let (state, t) = play_to_shard(i);
|
||||
println!("mission {}: state {} after {} s", i + 1, state, t);
|
||||
assert_eq!(state, 1, "mission {} not won", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn carry_over_takes_the_strongest() {
|
||||
let mut g = start_mission(0, None);
|
||||
|
||||
Reference in new issue
Block a user