Marks and dig selection in each master's colour; imps dig only their master's marks; AI marks near its ground, acts calmer, re-summons imps; allies never claim each other's ground

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-06 09:21:42 +01:00
1 parent 010a6a8a12
commit 773be21455
5 files changed
+161 -37

No files matched your search

+77
View File
@@ -468,6 +468,60 @@ mod tests {
assert!(ground > ground0 + 20, "the yellow master digs and claims: {} -> {}", ground0, ground);
}
#[test]
fn ai_marks_stay_near_its_ground_and_imps_dig_only_their_masters_marks() {
let mut g = rival_game(2);
let side = g.rivals[0].side;
let owner = Owner::of_side(side);
for _ in 0..(10 * 60 * 20) {
g.update(0.05);
if g.time as i32 % 20 == 0 {
for (i, t) in g.map.t.iter().enumerate() {
if t.marked && t.mark_by == side {
let (x, y) = crate::map::xy(i);
let near = (-5..=5).any(|dy| (-5..=5).any(|dx| g.map.get(x + dx, y + dy).map_or(false, |o| o.owner == owner)));
assert!(near, "AI mark at {},{} far from its ground", x, y);
}
}
}
}
// a foreign mark next to the player's imps stays untouched
let (cx, cy) = g.map.core;
let spot = (0..g.map.t.len()).find(|&i| {
let (x, y) = crate::map::xy(i);
(x - cx).abs() < 10 && (y - cy).abs() < 10 && g.map.t[i].kind == Kind::Earth && !g.map.t[i].marked
&& DIR4.iter().any(|&(dx, dy)| g.map.get(x + dx, y + dy).map_or(false, |o| o.owner == Owner::Player && o.walkable()))
}).expect("earth beside the player's floor");
g.map.t[spot].reinforced = false;
g.map.t[spot].marked = true;
g.map.t[spot].mark_by = side;
for _ in 0..(60 * 20) {
g.update(0.05);
}
assert_eq!(g.map.t[spot].kind, Kind::Earth, "the player's imps leave the AI's mark alone");
}
#[test]
fn the_ai_summons_new_imps_when_its_imps_die() {
let mut g = rival_game(1);
let side = g.rivals[0].side;
for _ in 0..(60 * 20) {
g.update(0.05);
}
for e in g.ents.iter_mut().filter(|e| e.alive && e.side == side && e.kind == EK::Worker) {
e.hp = 0.0;
}
for _ in 0..20 {
g.update(0.05);
}
assert_eq!(g.ents.iter().filter(|e| e.alive && e.side == side && e.kind == EK::Worker).count(), 0, "all its imps are dead");
for _ in 0..(3 * 60 * 20) {
g.update(0.05);
}
let imps = g.ents.iter().filter(|e| e.alive && e.side == side && e.kind == EK::Worker).count();
assert!(imps >= 2, "new imps (one per 80 mana, like the player): {}", imps);
}
#[test]
fn ai_dig_marks_carry_the_masters_side() {
let mut g = rival_game(1);
@@ -564,6 +618,29 @@ mod tests {
g
}
#[test]
fn imps_take_ground_from_enemies_but_never_from_allies() {
let mut g = offline_league_game();
assert!(g.allied(0, 2));
// a partner floor tile right beside the player's floor
let spot = (0..g.map.t.len()).find(|&i| {
let (x, y) = crate::map::xy(i);
g.map.t[i].kind == Kind::Floor && g.map.t[i].owner == Owner::Player
&& DIR4.iter().any(|&(dx, dy)| g.map.get(x + dx, y + dy).map_or(false, |o| o.kind == Kind::Floor && o.owner == Owner::Player))
&& x > 2 && y > 2
}).expect("player floor");
let (x, y) = crate::map::xy(spot);
let n = DIR4.iter().map(|&(dx, dy)| crate::map::idx(x + dx, y + dy)).find(|&j| g.map.t[j].owner == Owner::Player).unwrap();
g.map.t[n].owner = Owner::of_side(2);
g.map.t[n].reserved = 0;
assert!(!g.claimable(n, 999), "an ally's floor stays his");
// the same tile of an enemy master may be taken
g.coop = false;
g.teams = vec![(0, 0), (2, 1)];
assert!(!g.allied(0, 2));
assert!(g.claimable(n, 999), "an enemy's floor can be claimed");
}
#[test]
fn an_offline_coop_partner_is_an_allied_ai_master() {
let mut g = offline_league_game();