1
Fork 0

randomize playing field

This commit is contained in:
Andy Killorin 2026-11-09 14:55:30 -05:00
parent 5e72d94080
commit bd9412e54a
Signed by: ank
GPG key ID: 23F9463ECB67FE8C

View file

@ -1,5 +1,6 @@
use std::cmp::min; use std::cmp::min;
use std::collections::HashMap; use std::collections::HashMap;
use std::f32::consts::TAU;
use std::ptr; use std::ptr;
use macroquad::prelude::*; use macroquad::prelude::*;
@ -25,7 +26,8 @@ struct Robot {
impl Robot { impl Robot {
fn new(position: Vec2, team: Color) -> Self { 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} Self { pose, alive: true, collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team}
} }
@ -111,29 +113,31 @@ impl Food {
#[macroquad::main("Adversarial Foraging Simulator")] #[macroquad::main("Adversarial Foraging Simulator")]
async fn main() { async fn main() {
rand::srand(4);
let mut robots = Vec::new(); let mut robots = Vec::new();
let mut score = HashMap::new(); let mut score = HashMap::new();
for i in 5..20 { 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: 100.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: 1200.0, y: i as f32*50.0 }, BLUE));
} }
let mut food = Vec::new(); 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 0..120 {
for i in 5..20 { let x = rand::gen_range(200, 1100) as f32;
food.push(Food::new(Vec2 { x: i as f32*60.0, y: j as f32*50.0 })); 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())
} }
@ -141,17 +145,17 @@ async fn main() {
let mut loo = 0; let mut loo = 0;
loop { loop {
let rendered = loo %30 == 0;
clear_background(LIGHTGRAY); clear_background(LIGHTGRAY);
for food in &mut food{ for food in &mut food{
if let Some(team) = food.detect(robots.iter()) { if let Some(team) = food.detect(robots.iter()) {
if food.alive { if food.alive {
score.entry(color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1); score.entry(color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1);
println!("robot detected in contact");
food.alive = false; food.alive = false;
} }
} }
food.draw(); if rendered { food.draw(); }
// TODO: die upon collision with robot // TODO: die upon collision with robot
} }
@ -159,7 +163,6 @@ async fn main() {
let mut sensors = Vec::new(); let mut sensors = Vec::new();
for robot in &*robots { for robot in &*robots {
println!("loop");
let detect_food = robot.detect(food.iter().map(Food::collider)); 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_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)); 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); sensors.push(sensor);
} }
for (idx, robot) in robots.iter_mut().enumerate() { for (idx, robot) in robots.iter_mut().enumerate() {
robot.policy(&sensors[idx]); 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; loo += 1;
if loo %2 == 0 { if rendered {
next_frame().await // TODO: framerate cap next_frame().await // TODO: framerate cap
} }
} }