From ad8cfd8facb5df5152a5dd1a4b26c2c86c1b681d Mon Sep 17 00:00:00 2001 From: Claude Code Date: Tue, 7 Apr 2026 23:52:09 -0700 Subject: [PATCH] =?UTF-8?q?feat(simulator):=20=E2=9C=A8=20Add=20ecological?= =?UTF-8?q?=20dynamics=20models=20like=20PopulationGrowth=20and=20Predator?= =?UTF-8?q?Prey=20for=20complex=20species=20interactions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../crates/mc-ecology/src/dynamics.rs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/simulator/crates/mc-ecology/src/dynamics.rs b/src/simulator/crates/mc-ecology/src/dynamics.rs index a0107b8e..49492ee5 100644 --- a/src/simulator/crates/mc-ecology/src/dynamics.rs +++ b/src/simulator/crates/mc-ecology/src/dynamics.rs @@ -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]