Imps: at least 10% of the imps (min. one) claim floor while there is floor to claim

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 09:47:42 +01:00
1 parent 7f4324abca
commit c54998be55
1 file changed
+46
+46
View File
@@ -1541,6 +1541,19 @@ impl Game {
} }
} }
} }
// at least 10% of the imps (at least one) claim floor while there is floor to claim
let imps = 1 + self.ents.iter().filter(|o| o.alive && !o.hero && o.kind == EK::Worker).count();
let claiming = self.ents.iter().filter(|o| o.alive && !o.hero && o.kind == EK::Worker && matches!(o.job, Job::Claim(_))).count();
let quota = ((imps as f32 * 0.1).ceil() as usize).max(1);
if claiming < quota {
if let Some(p) = self.map.search(cur, self.map.walk_cost(), |i| self.claimable(i, me), true) {
let end = p.last().copied().unwrap_or(cur);
self.map.t[end].reserved = me;
e.path = p;
e.job = Job::Claim(end);
return;
}
}
if let Some(p) = self.map.search(cur, self.map.walk_cost(), |i| self.dig_neighbor(i, me).is_some(), true) { if let Some(p) = self.map.search(cur, self.map.walk_cost(), |i| self.dig_neighbor(i, me).is_some(), true) {
let end = p.last().copied().unwrap_or(cur); let end = p.last().copied().unwrap_or(cur);
if let Some(t) = self.dig_neighbor(end, me) { if let Some(t) = self.dig_neighbor(end, me) {
@@ -3101,6 +3114,39 @@ mod tests {
} }
} }
#[test]
fn some_imps_always_claim() {
// lots of digging work: still at least 10% (min. one) of the imps claim the dug-out floor
let mut g = Game::new(11, 64, 64);
let (cx, cy) = g.map.core;
for _ in 0..8 {
let (x, y) = (g.ents[0].x, g.ents[0].y);
g.spawn(EK::Worker, false, x, y, 1);
}
g.mark_rect(cx - 12, cy - 12, cx + 12, cy + 12, true);
let (mut samples, mut ok) = (0, 0);
for step in 0..(150 * 20) {
g.update(0.05);
if step % 20 != 0 || step < 200 {
continue;
}
let digging = g.map.t.iter().any(|t| t.marked);
let claimable = (0..g.map.t.len()).any(|i| g.claimable(i, u32::MAX));
if digging && claimable {
let imps = g.worker_count();
let quota = ((imps as f32 * 0.1).ceil() as usize).max(1);
let claiming = g.ents.iter().filter(|e| e.alive && e.kind == EK::Worker && matches!(e.job, Job::Claim(_))).count();
samples += 1;
if claiming >= quota {
ok += 1;
}
}
}
println!("claim quota met in {}/{} samples", ok, samples);
assert!(samples > 10);
assert!(ok * 10 >= samples * 8);
}
#[test] #[test]
fn imps_reinforce_walls() { fn imps_reinforce_walls() {
let mut g = Game::new(3, 64, 64); let mut g = Game::new(3, 64, 64);