diff --git a/simulator/src/main.rs b/simulator/src/main.rs index ca24220..e9f27d2 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -1,5 +1,6 @@ use std::cmp::min; use std::collections::HashMap; +use std::f32::consts::TAU; use std::ptr; use macroquad::prelude::*; @@ -25,7 +26,8 @@ struct Robot { impl Robot { fn new(position: Vec2, team: Color) -> Self { - let pose:Pose = Pose::from_translation(position.to_array().into()); + let rand_angle = rand::gen_range(0, 1000) as f32 * TAU / 1000.0; + let pose:Pose = Pose::from_parts(position.to_array().into(), Rot2::from_angle(rand_angle)); Self { pose, alive: true, collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team} } @@ -111,29 +113,31 @@ impl Food { #[macroquad::main("Adversarial Foraging Simulator")] async fn main() { + rand::srand(4); + let mut robots = Vec::new(); let mut score = HashMap::new(); for i in 5..20 { - robots.push(Robot::new(Vec2 { x: 150.0, y: i as f32*50.0 }, RED)); - robots.push(Robot::new(Vec2 { x: 1150.0, y: i as f32*50.0 }, BLUE)); + robots.push(Robot::new(Vec2 { x: 100.0, y: i as f32*50.0 }, RED)); + robots.push(Robot::new(Vec2 { x: 1200.0, y: i as f32*50.0 }, BLUE)); } let mut food = Vec::new(); - food.push(Food::new(Vec2 { x: 160.0, y: 100.0 })); - food.push(Food::new(Vec2 { x: 360.0, y: 100.0 })); - food.push(Food::new(Vec2 { x: 360.0, y: 300.0 })); - food.push(Food::new(Vec2 { x: 360.0, y: 400.0 })); - food.push(Food::new(Vec2 { x: 460.0, y: 400.0 })); - food.push(Food::new(Vec2 { x: 260.0, y: 400.0 })); - for j in 5..50 { - for i in 5..20 { - food.push(Food::new(Vec2 { x: i as f32*60.0, y: j as f32*50.0 })); - } + 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()) } @@ -141,17 +145,17 @@ async fn main() { let mut loo = 0; loop { + let rendered = loo %30 == 0; clear_background(LIGHTGRAY); for food in &mut food{ if let Some(team) = food.detect(robots.iter()) { if food.alive { score.entry(color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1); - println!("robot detected in contact"); food.alive = false; } } - food.draw(); + if rendered { food.draw(); } // TODO: die upon collision with robot } @@ -159,7 +163,6 @@ async fn main() { let mut sensors = Vec::new(); for robot in &*robots { - println!("loop"); let detect_food = robot.detect(food.iter().map(Food::collider)); let detect_kin = robot.detect(robots.iter().filter(|o| o.team == robot.team).filter(|r| !ptr::eq(&**r , &**&robot)).map(Robot::collider)); let detect_non_kin = robot.detect(robots.iter().filter(|o| o.team != robot.team).filter(|r| !ptr::eq(&**r , &**&robot)).map(Robot::collider)); @@ -179,19 +182,18 @@ async fn main() { } - println!("Food detection: {:?}",detect_food); - println!("Kin detection: {:?}",detect_kin); - println!("NonKin detection: {:?}",detect_non_kin); sensors.push(sensor); } for (idx, robot) in robots.iter_mut().enumerate() { robot.policy(&sensors[idx]); - robot.draw(); + if rendered { robot.draw();} + } + if rendered { + 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); } - 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, 90.0, 30.0, DARKGRAY); loo += 1; - if loo %2 == 0 { + if rendered { next_frame().await // TODO: framerate cap } }