From b9cfedc00daa9f456d1004448a10a9d62e72597d Mon Sep 17 00:00:00 2001 From: sparshg <43041139+sparshg@users.noreply.github.com> Date: Fri, 6 Jan 2023 02:03:25 +0530 Subject: [PATCH] cleanup --- src/asteroids.rs | 4 -- src/main.rs | 13 ----- src/nn.rs | 4 -- src/player.rs | 140 ++++++++++++++++++++-------------------------- src/population.rs | 15 ----- src/world.rs | 44 +-------------- 6 files changed, 63 insertions(+), 157 deletions(-) diff --git a/src/asteroids.rs b/src/asteroids.rs index a987fca..2eb9fef 100644 --- a/src/asteroids.rs +++ b/src/asteroids.rs @@ -72,7 +72,6 @@ impl Asteroid { } pub fn update(&mut self) { - // if self.alive { self.pos += self.vel; self.rot += self.omega; if self.pos.x.abs() > screen_width() * 0.5 + self.radius { @@ -81,9 +80,6 @@ impl Asteroid { if self.pos.y.abs() > screen_height() * 0.5 + self.radius { self.pos.y *= -1.; } - // self.alive = self.pos.y.abs() < screen_height() * 0.51 + self.radius - // && self.pos.x.abs() < screen_width() * 0.51 + self.radius; - // } } pub fn draw(&self) { diff --git a/src/main.rs b/src/main.rs index c48bbbe..71b77a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,6 @@ mod world; use macroquad::prelude::*; use population::Population; -use world::World; #[macroquad::main("Camera")] async fn main() { @@ -18,9 +17,6 @@ async fn main() { set_camera(&cam); let mut pop = Population::new(100); let mut speedup = false; - // for _ in 0..10000 * 10 { - // pop.update(); - // } loop { clear_background(BLACK); if is_key_pressed(KeyCode::S) { @@ -36,13 +32,4 @@ async fn main() { } next_frame().await } - // let mut world = World::new(); - // loop { - // clear_background(BLACK); - // if !world.over { - // world.update(); - // } - // world.draw(); - // next_frame().await - // } } diff --git a/src/nn.rs b/src/nn.rs index e6eafcf..37f0e00 100644 --- a/src/nn.rs +++ b/src/nn.rs @@ -39,9 +39,6 @@ impl NN { .zip(config.iter().skip(1)) .map(|(&curr, &last)| { // DMatrix::from_fn(last, curr + 1, |_, _| gen_range(-1., 1.)) - // DMatrix::::new_random(last, curr + 1) - // println!("{}", a); - // a DMatrix::::from_distribution(last, curr + 1, &StandardNormal, &mut rng) * (2. / last as f32).sqrt() }) @@ -75,7 +72,6 @@ impl NN { // *ele += gen_range(-1., 1.); *ele = gen_range(-1., 1.); // *ele = r::thread_rng().sample::(StandardNormal); - // *ele = r::thread_rng().sample::(StandardNormal); } } } diff --git a/src/player.rs b/src/player.rs index ebcc9b3..fa5bf19 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,6 @@ use std::{f32::consts::PI, f64::consts::TAU, iter}; use macroquad::{prelude::*, rand::gen_range}; -use nalgebra::{max, partial_max, partial_min}; use crate::{asteroids::Asteroid, nn::NN}; #[derive(Default)] @@ -58,35 +57,29 @@ impl Player { } pub fn check_player_collision(&mut self, asteroid: &Asteroid) -> bool { - // let directions = [ - // vec2(0., -screen_height()), - // vec2(0., screen_height()), - // vec2(-screen_width(), 0.), - // vec2(screen_width(), 0.), - // ]; - // let mut nearest = asteroid.pos - self.pos; - // for dir in directions { - // if (asteroid.pos - self.pos + dir).length_squared() < nearest.length_squared() { - // nearest = asteroid.pos - self.pos + dir; - // } - // } - self.asteroid_data.push(( - ((asteroid.pos - self.pos).length() - asteroid.radius) / screen_width(), - self.dir.angle_between(asteroid.pos - self.pos), - (asteroid.vel - self.vel).length(), - )); - // if self.asteroid.is_none() - // || (asteroid.pos).distance_squared(self.pos) - // < self - // .asteroid - // .as_ref() - // .unwrap() - // .pos - // .distance_squared(self.pos) - // { - // self.asteroid = Some(asteroid.clone()); - // } - // ]); + // To give more near asteroids data: + + // self.asteroid_data.push(( + // ((asteroid.pos - self.pos).length() - asteroid.radius) / screen_width(), + // self.dir.angle_between(asteroid.pos - self.pos), + // (asteroid.vel - self.vel).length(), + // )); + + // Single asteroid data: + if self.asteroid.is_none() + || (asteroid.pos).distance_squared(self.pos) + < self + .asteroid + .as_ref() + .unwrap() + .pos + .distance_squared(self.pos) + { + self.asteroid = Some(asteroid.clone()); + } + + // Try raycasting below: + // let v = asteroid.pos - self.pos; // for i in 0..4 { // let dir = Vec2::from_angle(PI / 4. * i as f32).rotate(self.dir); @@ -125,35 +118,29 @@ impl Player { self.last_shot += 1; self.acc = 0.; let mut keys = vec![false, false, false, false]; - let mut inputs = vec![ - // (self.asteroid.as_ref().unwrap().pos - self.pos).length() / screen_width(), - // self.dir - // .angle_between(self.asteroid.as_ref().unwrap().pos - self.pos), - // self.vel.x / 11., - // self.vel.y / 11., - self.rot / TAU as f32, - // self.rot.sin(), - // self.rot.cos(), - ]; + if let Some(ast) = self.asteroid.as_ref() { + let inputs = vec![ + (ast.pos - self.pos).length() / screen_width(), + self.dir.angle_between(ast.pos - self.pos), + (ast.vel - self.vel).length(), + self.rot / TAU as f32, + ]; - self.asteroid_data - .sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); - self.asteroid_data.resize(1, (0., 0., 0.)); - inputs.append( - &mut self - .asteroid_data - .iter() - .map(|(d, a, h)| vec![*d, *a, *h]) - .flatten() - .collect::>(), - ); - // println!("{:?}", inputs); - // let inputs = self.raycasts.clone(); - // inputs.append(self.asteroids_data.as_mut()); - if let Some(brain) = &self.brain { - // println!("{:?}", brain.feed_forward(inputs.clone())); + // self.asteroid_data + // .sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); + // self.asteroid_data.resize(1, (0., 0., 0.)); + // inputs.append( + // &mut self + // .asteroid_data + // .iter() + // .map(|(d, a, h)| vec![*d, *a, *h]) + // .flatten() + // .collect::>(), + // ); - keys = brain.feed_forward(inputs).iter().map(|&x| x > 0.).collect(); + if let Some(brain) = &self.brain { + keys = brain.feed_forward(inputs).iter().map(|&x| x > 0.).collect(); + } } if is_key_down(KeyCode::Right) && self.debug || keys[0] { self.rot = (self.rot + 0.1 + TAU as f32) % TAU as f32; @@ -164,7 +151,6 @@ impl Player { self.dir = vec2(self.rot.cos(), self.rot.sin()); } if is_key_down(KeyCode::Up) && self.debug || keys[2] { - // Change scaling when passing inputs if this is changed self.acc = 0.14; } if is_key_down(KeyCode::Space) && self.debug || keys[3] { @@ -182,6 +168,9 @@ impl Player { if is_key_pressed(KeyCode::D) { self.debug = !self.debug; } + if is_key_pressed(KeyCode::S) { + self.debug = false; + } self.vel += self.acc * self.dir - self.drag * self.vel.length() * self.vel; self.pos += self.vel; @@ -198,9 +187,11 @@ impl Player { self.bullets.retain(|b| { b.alive && b.pos.x.abs() * 2. < screen_width() && b.pos.y.abs() * 2. < screen_height() }); - // self.draw(); + if self.debug { + self.draw(); + } self.asteroid = None; - self.asteroid_data.clear(); + // self.asteroid_data.clear(); } pub fn draw(&self) { @@ -223,25 +214,16 @@ impl Player { draw_triangle_lines(p6, p7, p8, 2., color); } if self.debug { - // if self.asteroid.is_some() { - // draw_circle_lines( - // self.asteroid.as_ref().unwrap().pos.x, - // self.asteroid.as_ref().unwrap().pos.y, - // self.asteroid.as_ref().unwrap().radius, - // 1., - // GRAY, - // ); - // } - let p = self.pos - + self.dir.rotate(Vec2::from_angle(self.asteroid_data[0].1)) - * self.asteroid_data[0].0 - * screen_width(); - draw_line( - self.pos.x, self.pos.y, - // self.asteroid.as_ref().unwrap().pos.x, - // self.asteroid.as_ref().unwrap().pos.y, - p.x, p.y, 1., GRAY, - ); + if let Some(ast) = self.asteroid.as_ref() { + draw_circle_lines(ast.pos.x, ast.pos.y, ast.radius, 1., GRAY); + // let p = self.pos + // + self.dir.rotate(Vec2::from_angle(self.asteroid_data[0].1)) + // * self.asteroid_data[0].0 + // * screen_width(); + draw_line(self.pos.x, self.pos.y, ast.pos.x, ast.pos.y, 1., GRAY); + } + + // Draw raycasts // for (i, r) in self.raycasts.iter().enumerate() { // let dir = Vec2::from_angle(PI / 4. * i as f32).rotate(self.dir); diff --git a/src/population.rs b/src/population.rs index 1cd4c31..f5480a2 100644 --- a/src/population.rs +++ b/src/population.rs @@ -63,22 +63,12 @@ impl Population { println!("Fitness: {}", i.fitness); } println!("Gen: {}, Fitness: {}", self.gen, self.worlds[0].fitness); - // let mut new_worlds = vec![World::simulate(Some(self.worlds[0].see_brain().to_owned()))]; let mut new_worlds = (0..self.size / 20) .map(|i| World::simulate(Some(self.worlds[i].see_brain().to_owned()))) .collect::>(); - // if is_key_down(KeyCode::K) { new_worlds[0].set_best(); - // } - // println!( - // "Total fitness: {} {} {}", - // total, - // self.worlds[0].fitness(), - // self.worlds[1].fitness() - // ); while new_worlds.len() < self.size { let rands = (gen_range(0., total), gen_range(0., total)); - // println!("rands: {} {} {}", rands.0, rands.1, total); let mut sum = 0.; let (mut a, mut b) = (None, None); for world in &self.worlds { @@ -90,8 +80,6 @@ impl Population { b = Some(world.see_brain()); } } - // println!("{}", &a.unwrap().weights[0]); - // println!("{}", &b.unwrap().weights[0]); if a.is_none() { a = Some(self.worlds.last().unwrap().see_brain()); } @@ -99,10 +87,7 @@ impl Population { b = Some(self.worlds.last().unwrap().see_brain()); } let mut new_brain = NN::crossover(a.unwrap(), b.unwrap()); - // println!("{}", &a.unwrap().weights[0]); - // println!("{}", &b.unwrap().weights[0]); new_brain.mutate(); - // println!("{}", &new_brain.weights[0]); new_worlds.push(World::simulate(Some(new_brain))); } self.worlds = new_worlds; diff --git a/src/world.rs b/src/world.rs index fd4e782..1c25858 100644 --- a/src/world.rs +++ b/src/world.rs @@ -11,24 +11,13 @@ pub struct World { asteroids: Vec, pub score: f32, pub over: bool, - max_asteroids: usize, pub fitness: f32, } impl World { - pub fn new() -> Self { - Self { - player: Player::new(), - max_asteroids: 28, - score: 1., - ..Default::default() - } - } - pub fn simulate(brain: Option) -> Self { Self { player: Player::simulate(brain), - max_asteroids: 28, score: 1., asteroids: vec![ Asteroid::new_to(vec2(0., 0.), 1.5, AsteroidSize::Large), @@ -49,30 +38,7 @@ impl World { self.player.brain.as_ref().unwrap() } - // fn calc_fitness(&mut self) { - // println!( - // "{} {} {}", - // self.score as f32, - // self.player.lifespan as f32 * 0.001, - // if self.player.shots > 0 { - // self.score as f32 / self.player.shots as f32 * 5. - // } else { - // 0. - // } - // ); - // } - pub fn update(&mut self) { - // if self.player.lifespan > 150 { - // self.fitness = 1. - // / ((self.player.pos * vec2(2. / screen_width(), 2. / screen_height())) - // .distance_squared(vec2(0., -1.)) - // + self.player.vel.length_squared() - // * self.player.vel.length_squared() - // * 0.00006830134554 - // + 1.); - // self.over = true; - // } let mut to_add: Vec = Vec::new(); for asteroid in &mut self.asteroids { asteroid.update(); @@ -108,19 +74,15 @@ impl World { _ => {} } } - } - for asteroid in self.asteroids.iter() { - if self.player.check_player_collision(&*asteroid) { + if self.player.check_player_collision(asteroid) { self.over = true; self.fitness = (self.score / self.player.shots as f32).powi(2) * self.player.lifespan as f32; - - // println!("{} {} {}", self.score, self.player.lifespan, self.fitness); } } + self.player.update(); self.asteroids.append(&mut to_add); self.asteroids.retain(|asteroid| asteroid.alive); - self.player.update(); // if self.asteroids.iter().fold(0, |acc, x| { // acc + match x.size { // AsteroidSize::Large => 4, @@ -146,8 +108,6 @@ impl World { "{}", (self.score / self.player.shots as f32).powi(2) * self.player.lifespan as f32 ), - // 20. - screen_width() * 0.5, - // 30. - screen_height() * 0.5, self.player.pos.x - 20., self.player.pos.y - 20., 12.,