1
Fork 0

define mortality

This commit is contained in:
Andy Killorin 2026-11-09 15:50:07 -05:00
parent 3d9f957c4f
commit 596db89430
Signed by: ank
GPG key ID: 23F9463ECB67FE8C

View file

@ -2,6 +2,8 @@ use std::cmp::min;
use std::collections::HashMap;
use std::f32::consts::TAU;
use std::ptr;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use macroquad::prelude::*;
use parry2d::math::Pose;
@ -16,19 +18,48 @@ use parry2d::shape::Shape;
const VIEW_DIST: f32 = 180.0;
const BOT_RADIUS: f32 = 16.0;
trait Mortal {
fn collider(&self) -> (&Pose, &dyn Shape);
fn kill(&self);
fn living(&self) -> bool;
fn draw(&self);
}
struct Robot {
pose: Pose,
alive: bool,
alive: AtomicBool,
collider: Ball,
sensor: Sensor,
team: Color,
}
impl Mortal for Robot {
fn draw(&self) {
let tl = self.pose.translation;
let tl2 = self.view_end();
draw_circle(tl.x, tl.y, BOT_RADIUS, BLACK);
draw_line(tl.x, tl.y, tl2.x, tl2.y, 2.0, BLUE);
draw_circle(tl.x, tl.y, BOT_RADIUS-1.0, self.team);
}
fn collider(&self) -> (&Pose, &dyn Shape) {
(&self.pose, &self.collider)
}
fn kill (&self) {
self.alive.store(false, Ordering::Relaxed);
}
fn living(&self) -> bool {
self.alive.load(Ordering::Relaxed)
}
}
impl Robot {
fn new(position: Vec2, team: Color) -> Self {
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: AtomicBool::new(true), collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team}
}
fn move_step(&mut self, forward: f32, right: f32) {
@ -40,21 +71,10 @@ impl Robot {
Vec2::new(self.pose.rotation.re, self.pose.rotation.im)
}
pub fn draw(&self) {
let tl = self.pose.translation;
let tl2 = self.view_end();
draw_circle(tl.x, tl.y, BOT_RADIUS, BLACK);
draw_line(tl.x, tl.y, tl2.x, tl2.y, 2.0, BLUE);
draw_circle(tl.x, tl.y, BOT_RADIUS-1.0, self.team);
}
fn view_end(&self) -> Vec2 {
self.pose.translation + self.ahead() * VIEW_DIST
}
pub fn collider(&self) -> (&Pose, &dyn Shape) {
(&self.pose, &self.collider)
}
fn detect<'a>(&self, things: impl Iterator<Item = (&'a Pose, &'a dyn Shape)>) -> Option<f32> {
let collider = Segment::new(self.pose.translation, self.view_end());
@ -76,7 +96,7 @@ impl Robot {
struct Food {
pose: Pose,
collider: Ball,
alive: bool,
alive: AtomicBool,
}
enum Sensor {
@ -86,22 +106,33 @@ enum Sensor {
None
}
impl Food {
fn new(position: Vec2) -> Self {
let pose:Pose = Pose::from_translation(position.to_array().into());
Self { pose, alive: true, collider: Ball::new(BOT_RADIUS) }
}
pub fn draw(&self) {
impl Mortal for Food {
fn draw(&self) {
let tl = self.pose.translation;
draw_circle(tl.x, tl.y, BOT_RADIUS, BLACK);
draw_circle(tl.x, tl.y, BOT_RADIUS-1.0, GREEN);
}
pub fn collider(&self) -> (&Pose, &dyn Shape) {
fn collider(&self) -> (&Pose, &dyn Shape) {
(&self.pose, &self.collider)
}
fn kill (&self) {
self.alive.store(false, Ordering::Relaxed);
}
fn living(&self) -> bool {
self.alive.load(Ordering::Relaxed)
}
}
impl Food {
fn new(position: Vec2) -> Self {
let pose:Pose = Pose::from_translation(position.to_array().into());
Self { pose, alive: AtomicBool::new(true), collider: Ball::new(BOT_RADIUS) }
}
fn detect<'a>(&self, things: impl Iterator<Item = &'a Robot>) -> Option<Color> {
things
.map(|robot| contact(&self.pose, &self.collider, &robot.pose, &robot.collider, 0.0).unwrap().map(|a| (a,robot.team))).flatten()
@ -140,21 +171,21 @@ async fn run_simulation() -> (i32, i32) {
let mut loo = 0;
loop {
let rendered = loo %30 == 0;
let rendered = loo %100 == 0;
clear_background(LIGHTGRAY);
for food in &mut food{
if let Some(team) = food.detect(robots.iter()) {
if food.alive {
if food.living() {
score.entry(color_hash(team)).and_modify(|s| *s +=1 ).or_insert(1);
food.alive = false;
food.kill();
}
}
if rendered { food.draw(); }
// TODO: die upon collision with robot
}
food = food.into_iter().filter(|f| f.alive).collect(); // remove dead food
food = food.into_iter().filter(Mortal::living).collect(); // remove dead food
let mut sensors = Vec::new();
for robot in &*robots {