1
Fork 0

extract simulator into struct

This commit is contained in:
Andy Killorin 2026-11-09 18:23:19 -05:00
parent ada386fb30
commit d2408b2468
Signed by: ank
GPG key ID: 23F9463ECB67FE8C

View file

@ -167,55 +167,59 @@ impl Food {
} }
} }
async fn run_simulation() -> (i32, i32) { struct Simulation {
let mut watchdog = 0; // iterations since something interesting robots: Vec<Robot>,
let mut robots = Vec::new(); food: Vec<Food>,
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(); impl Simulation {
let mut new_craters: Vec<(f32, f32, f32, Color)> = Vec::new(); 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 { let score = HashMap::new();
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)); 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] { fn color_hash(color: Color) -> [u32; 4] {
color.to_vec().to_array().map(|f| f.to_bits()) 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; for food in &*food{
loop {
let rendered = loo %490 == 0;
for food in &mut food{
if let Some(team) = food.detect(robots.iter()) { if let Some(team) = food.detect(robots.iter()) {
if food.living() { 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(); food.kill();
watchdog = 0; *watchdog = 0;
} }
} }
} }
food = food.into_iter().filter(Mortal::living).collect(); // remove dead food food.retain(Mortal::living);
robots = robots.into_iter().filter(Mortal::living).collect(); // remove dead robots robots.retain(Mortal::living);
let mut sensors = Vec::new(); let mut sensors = Vec::new();
for robot in &*robots { for robot in &*robots {
@ -258,36 +262,58 @@ async fn run_simulation() -> (i32, i32) {
} }
} }
if rendered { *watchdog += 1;
clear_background(LIGHTGRAY); if food.is_empty() || *watchdog > 1000 {
for crater in &new_craters { let red = score.get(&Self::color_hash(RED)).unwrap_or(&0);
draw_circle(crater.0, crater.1, crater.2, crater.3); let blu = score.get(&Self::color_hash(BLUE)).unwrap_or(&0);
} return Some((*red, *blu));
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);
} }
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 {
sim.render().await
}
if let Some(result) = result {
return result;
}
loo += 1; 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);
}
} }
} }