feat(simulator): Add ecological dynamics models like PopulationGrowth and PredatorPrey for complex species interactions

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-04-07 23:52:09 -07:00
parent d2679917c1
commit ad8cfd8fac

View file

@ -918,6 +918,7 @@ mod tests {
#[test]
fn predation_efficiency_sessile_prey_always_caught() {
// A sessile prey (flee_speed=0) is always caught once detected.
// Chase probability should be 1.0 regardless of predator pursuit speed.
let pred = wolf();
let mut prey = Species::derive_from_traits(
60,
@ -934,11 +935,26 @@ mod tests {
);
prey.resolve_derived_stats();
// flee_speed derived = 0 for Sessile
// Override concealment to isolate the chase=1.0 behaviour under test —
// otherwise a highly concealed sessile species drops detection below 0.5
// and obscures what we're actually measuring.
prey.evasion.concealment = 5;
let eff = predation_efficiency(&pred, &prey, "ocean");
// chase = pursuit / (pursuit + 0) = 1.0
// efficiency = detection × 1.0 = detection
assert!(eff > 0.5, "Sessile prey should have high chase probability (flee=0), got {eff}");
// detection = 10 / (10 + 5) ≈ 0.667
// chase = 1.0 (sessile — flee_speed=0 forces chase to 1.0)
// efficiency ≈ 0.667
assert!(eff > 0.6, "Sessile prey with moderate concealment should give eff > 0.6, got {eff}");
// Also verify that a predator with pursuit=0 still catches sessile prey (chase=1.0),
// since neither can move so the prey remains reachable.
let mut still_pred = pred.clone();
still_pred.interaction.pursuit_speed = 0;
let eff_still = predation_efficiency(&still_pred, &prey, "ocean");
assert!(
eff_still > 0.6,
"Sessile prey should still be caught by stationary predator (chase=1.0), got {eff_still}",
);
}
#[test]