diff --git a/simulator/src/main.rs b/simulator/src/main.rs index b433c83..166d98e 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -167,55 +167,59 @@ impl Food { } } -async fn run_simulation() -> (i32, i32) { - let mut watchdog = 0; // iterations since something interesting - let mut robots = Vec::new(); +struct Simulation { + robots: Vec, + food: Vec, + craters: Vec<(f32, f32, f32, Color)>, + new_craters: Vec<(f32, f32, f32, Color)>, + watchdog: i32, + score: HashMap<[u32;4], i32>, +} - let mut craters: Vec<(f32, f32, f32, Color)> = Vec::new(); - let mut new_craters: Vec<(f32, f32, f32, Color)> = Vec::new(); +impl Simulation { + fn new() -> Self { + let watchdog = 0; // iterations since something interesting + let mut robots = Vec::new(); - let mut score = HashMap::new(); + let craters: Vec<(f32, f32, f32, Color)> = Vec::new(); + let new_craters: Vec<(f32, f32, f32, Color)> = Vec::new(); - for i in 5..20 { - robots.push(Robot::new(Vec2 { x: 100.0, y: i as f32*50.0 }, BLUE)); - robots.push(Robot::new(Vec2 { x: 1200.0, y: i as f32*50.0 }, RED)); + let score = HashMap::new(); + + for i in 5..20 { + robots.push(Robot::new(Vec2 { x: 100.0, y: i as f32*50.0 }, BLUE)); + robots.push(Robot::new(Vec2 { x: 1200.0, y: i as f32*50.0 }, RED)); + } + + let mut food = Vec::new(); + + for _ in 0..120 { + let x = rand::gen_range(200, 1100) as f32; + let y = rand::gen_range(200, 900) as f32; + food.push(Food::new(Vec2 { x, y })); + } + Self { robots, food, craters, new_craters, watchdog, score } } - let mut food = Vec::new(); - - for i in 0..120 { - let x = rand::gen_range(200, 1100) as f32; - let y = rand::gen_range(200, 900) as f32; - food.push(Food::new(Vec2 { x, y })); - } - - //for j in 5..20 { - // for i in 5..20 { - // food.push(Food::new(Vec2 { x: i as f32*60.0, y: j as f32*50.0 })); - // } - //} - fn color_hash(color: Color) -> [u32; 4] { color.to_vec().to_array().map(|f| f.to_bits()) } + fn sim_step(&mut self) -> Option<(i32, i32)>{ + let Simulation { robots, food, craters, new_craters, watchdog, score } = self; - let mut loo = 1; - loop { - let rendered = loo %490 == 0; - - for food in &mut food{ + for food in &*food{ if let Some(team) = food.detect(robots.iter()) { if food.living() { - score.entry(color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1); + score.entry(Self::color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1); food.kill(); - watchdog = 0; + *watchdog = 0; } } } - food = food.into_iter().filter(Mortal::living).collect(); // remove dead food - robots = robots.into_iter().filter(Mortal::living).collect(); // remove dead robots + food.retain(Mortal::living); + robots.retain(Mortal::living); let mut sensors = Vec::new(); for robot in &*robots { @@ -257,37 +261,59 @@ async fn run_simulation() -> (i32, i32) { robot.weapon(peers); } } + + *watchdog += 1; + if food.is_empty() || *watchdog > 1000 { + let red = score.get(&Self::color_hash(RED)).unwrap_or(&0); + let blu = score.get(&Self::color_hash(BLUE)).unwrap_or(&0); + return Some((*red, *blu)); + } + None + } + + async fn render(&mut self) { + let Simulation { robots, food, craters, new_craters, watchdog: _, score } = self; + + clear_background(LIGHTGRAY); + for crater in &*new_craters { + draw_circle(crater.0, crater.1, crater.2, crater.3); + } + craters.append(&mut *new_craters); + for crater in &*craters { + draw_circle(crater.0, crater.1, crater.2, Color::new(0.75, 0.75, 0.75, 1.0)); + } + for food in &*food { + food.draw(); + + } + for robot in &*robots { + robot.draw(); + } + draw_text(format!("RED: {}", score.get(&Self::color_hash(RED)).unwrap_or(&0)), 20.0, 20.0, 30.0, DARKGRAY); + draw_text(format!("BLUE: {}", score.get(&Self::color_hash(BLUE)).unwrap_or(&0)), 20.0, 40.0, 30.0, DARKGRAY); + next_frame().await // TODO: framerate cap + } +} + +async fn run_simulation() -> (i32, i32) { + let mut sim = Simulation::new(); + + + + let mut loo = 1; + loop { + let rendered = loo % 20 == 0; + let result = sim.sim_step(); if rendered { - clear_background(LIGHTGRAY); - for crater in &new_craters { - draw_circle(crater.0, crater.1, crater.2, crater.3); - } - craters.append(&mut new_craters); - for crater in &craters { - draw_circle(crater.0, crater.1, crater.2, Color::new(0.75, 0.75, 0.75, 1.0)); - } - for food in &food { - food.draw(); - - } - for robot in &robots { - robot.draw(); - } - draw_text(format!("RED: {}", score.get(&color_hash(RED)).unwrap_or(&0)), 20.0, 20.0, 30.0, DARKGRAY); - draw_text(format!("BLUE: {}", score.get(&color_hash(BLUE)).unwrap_or(&0)), 20.0, 40.0, 30.0, DARKGRAY); + sim.render().await } + + if let Some(result) = result { + return result; + } + loo += 1; - if rendered { - next_frame().await // TODO: framerate cap - } - - watchdog += 1; - if food.is_empty() || watchdog > 1000 { - let red = score.get(&color_hash(RED)).unwrap_or(&0); - let blu = score.get(&color_hash(BLUE)).unwrap_or(&0); - return (*red, *blu); - } } }