#[path="../korean_telemetry.rs"] mod korean_telemetry; use rand::Rng; use korean_telemetry::TelemetryReporter; #[derive(Copy, Clone, Debug, PartialEq)] pub enum PhaseState { HyperInhibition, StandardInhibition, SubInhibition, NegQuiescent, PosQuiescent, SubExcitation, StandardExcitation, HyperExcitation, } impl PhaseState { pub fn value(&self) -> f32 { match self { PhaseState::HyperInhibition => -2.0, PhaseState::StandardInhibition => -1.0, PhaseState::SubInhibition => -0.5, PhaseState::NegQuiescent => -0.01, PhaseState::PosQuiescent => 0.01, PhaseState::SubExcitation => 0.5, PhaseState::StandardExcitation => 1.0, PhaseState::HyperExcitation => 2.0, } } pub fn from_energy(e: f32) -> Self { if e <= -1.5 { PhaseState::HyperInhibition } else if e <= -0.75 { PhaseState::StandardInhibition } else if e <= -0.25 { PhaseState::SubInhibition } else if e <= 0.0 { PhaseState::NegQuiescent } else if e <= 0.25 { PhaseState::PosQuiescent } else if e <= 0.75 { PhaseState::SubExcitation } else if e <= 1.5 { PhaseState::StandardExcitation } else { PhaseState::HyperExcitation } } } pub struct BioPhysPlanetEngine { pub size: usize, pub bedrock: Vec, pub topsoil: Vec, pub mutation_rate: f32, } impl BioPhysPlanetEngine { pub fn new(size: usize, mutation_rate: f32) -> Self { let mut rng = rand::thread_rng(); let bedrock: Vec = (0..size * size) .map(|i| { let x = (i % size) as f32; let y = (i / size) as f32; ((x * 0.3).sin() + (y * 0.3).cos()) * 0.5 }) .collect(); let topsoil: Vec = (0..size * size) .map(|_| PhaseState::from_energy(rng.gen_range(-2.0..2.0))) .collect(); BioPhysPlanetEngine { size, bedrock, topsoil, mutation_rate } } pub fn step(&mut self) -> f32 { let mut rng = rand::thread_rng(); let mut next_topsoil = self.topsoil.clone(); let mut total_energy = 0.0f32; let s = self.size as i32; for y in 0..s { for x in 0..s { let idx = (y * s + x) as usize; let neighbors = [ ((y - 1 + s) % s * s + x) as usize, ((y + 1) % s * s + x) as usize, (y * s + (x - 1 + s) % s) as usize, (y * s + (x + 1) % s) as usize, ]; let neighbor_energy: f32 = neighbors.iter() .map(|&n_idx| self.topsoil[n_idx].value()) .sum::() * 0.25; let mut local_field = neighbor_energy + self.bedrock[idx]; if rng.gen_bool(self.mutation_rate as f64) { local_field += rng.gen_range(-0.5..0.5); } let new_phase = PhaseState::from_energy(local_field); next_topsoil[idx] = new_phase; total_energy += local_field.abs(); } } self.topsoil = next_topsoil; total_energy / (self.size * self.size) as f32 } pub fn get_phase_values(&self) -> Vec { self.topsoil.iter().map(|p| p.value()).collect() } } fn main() { println!("============================================================"); println!(" 🌍 BioPhys 8-State μ—”μ§„ & μ‹€μ‹œκ°„ ν•œκ΅­μ–΄ ν…”λ ˆλ©”νŠΈλ¦¬ 연동"); println!("============================================================\n"); let grid_size = 16; let mutation_rate = 0.05; let mut engine = BioPhysPlanetEngine::new(grid_size, mutation_rate); for tick in 1..=5 { let avg_energy = engine.step(); let phases = engine.get_phase_values(); let report = TelemetryReporter::analyze(&phases, avg_energy, tick); println!("{}", report); } println!("============================================================"); println!(" βœ… ν•œκ΅­μ–΄ ν…”λ ˆλ©”νŠΈλ¦¬ νŒŒμ΄ν”„λΌμΈ 연동 μ™„λ£Œ"); println!("============================================================"); }