From 666c9a8b8e9e0662204932ea0ccf3c5156ef87fe Mon Sep 17 00:00:00 2001 From: sparshg <43041139+sparshg@users.noreply.github.com> Date: Tue, 11 Oct 2022 01:13:05 +0530 Subject: [PATCH] pop done --- src/asteroids.rs | 2 +- src/main.rs | 16 +++++++++++++--- src/player.rs | 21 +++++++++++++-------- src/population.rs | 20 +++++++++++--------- src/world.rs | 10 ++++++++++ 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/asteroids.rs b/src/asteroids.rs index 97f9e76..937cfb4 100644 --- a/src/asteroids.rs +++ b/src/asteroids.rs @@ -89,7 +89,7 @@ impl Asteroid { AsteroidSize::Medium => 1.2, AsteroidSize::Small => 0.8, }, - WHITE, + Color::new(1., 1., 1., 0.5), ); } } diff --git a/src/main.rs b/src/main.rs index 9074fb7..53cb979 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,11 +16,21 @@ async fn main() { ..Default::default() }; set_camera(&cam); - let mut pop = Population::new(5); + let mut pop = Population::new(100); + let mut speedup = false; loop { clear_background(BLACK); - pop.update(); - pop.draw(); + if is_key_pressed(KeyCode::S) { + speedup = !speedup; + } + if speedup { + for _ in 0..100 { + pop.update(); + } + } else { + pop.update(); + pop.draw(); + } next_frame().await } // let mut world = World::new(); diff --git a/src/player.rs b/src/player.rs index 9cf92ec..8e8657b 100644 --- a/src/player.rs +++ b/src/player.rs @@ -14,11 +14,12 @@ pub struct Player { last_shot: f32, shot_interval: f32, pub brain: Option, - search_radius: f32, - proximity_asteroids: Vec, + asteroids_data: Vec, max_asteroids: usize, debug: bool, alive: bool, + pub lifespan: u32, + pub shots: u32, } impl Player { @@ -30,7 +31,6 @@ impl Player { // Change scaling when passing inputs if this is changed drag: 0.001, shot_interval: 0.3, - search_radius: 300., alive: true, debug: false, ..Default::default() @@ -50,8 +50,11 @@ impl Player { } pub fn check_player_collision(&mut self, asteroid: &mut Asteroid) -> bool { - self.proximity_asteroids - .extend([asteroid.pos.x, asteroid.pos.y, asteroid.radius]); + self.asteroids_data.extend([ + asteroid.pos.x / screen_width() + 0.5, + asteroid.pos.y / screen_height() + 0.5, + asteroid.radius / 50., + ]); if asteroid.check_collision(self.pos, 8.) { self.alive = false; return true; @@ -71,10 +74,11 @@ impl Player { } pub fn update(&mut self) { + self.lifespan += 1; let mut mag = 0.; let mut keys = vec![false, false, false, false]; - self.proximity_asteroids.resize(self.max_asteroids, 0.); + self.asteroids_data.resize(self.max_asteroids, 0.); let mut inputs = vec![ self.pos.x / screen_width() + 0.5, self.pos.y / screen_height() + 0.5, @@ -82,7 +86,7 @@ impl Player { self.vel.y / 11., self.rot / TAU as f32, ]; - inputs.append(self.proximity_asteroids.as_mut()); + inputs.append(self.asteroids_data.as_mut()); if let Some(brain) = &self.brain { keys = brain .feed_forward(inputs) @@ -105,6 +109,7 @@ impl Player { if is_key_down(KeyCode::Space) || keys[3] { if self.shot_interval + self.last_shot < get_time() as f32 { self.last_shot = get_time() as f32; + self.shots += 1; self.bullets.push(Bullet { pos: self.pos + self.dir.rotate(vec2(20., 0.)), vel: self.dir.rotate(vec2(8.5, 0.)) + self.vel, @@ -151,7 +156,7 @@ impl Player { } if self.debug { - for a in self.proximity_asteroids.chunks(3) { + for a in self.asteroids_data.chunks(3) { draw_circle_lines(a[0], a[1], a[2], 1., GRAY); draw_line(self.pos.x, self.pos.y, a[0], a[1], 1., GRAY) } diff --git a/src/population.rs b/src/population.rs index 3187a2b..618178b 100644 --- a/src/population.rs +++ b/src/population.rs @@ -14,7 +14,7 @@ impl Population { Self { size, worlds: (0..size) - .map(|_| World::simulate(NN::new(vec![33, 10, 4]))) + .map(|_| World::simulate(NN::new(vec![33, 16, 4]))) .collect(), ..Default::default() } @@ -30,6 +30,7 @@ impl Population { } if !alive { self.gen += 1; + println!("{}", self.gen); self.next_gen(); } } @@ -50,18 +51,19 @@ impl Population { } pub fn next_gen(&mut self) { - let total = self.worlds.iter().fold(0, |acc, x| acc + x.score); - self.worlds.sort_by(|a, b| b.score.cmp(&a.score)); - let mut new_worlds = (0..self.size / 10) - .map(|i| World::simulate(self.worlds[i].see_brain().to_owned())) - .collect::>(); + let total = self.worlds.iter().fold(0., |acc, x| acc + x.fitness()); + // self.worlds.sort_by(|a, b| b.fitness().cmp(&a.fitness())); + let mut new_worlds = Vec::new(); + // (0..self.size / 10) + // .map(|i| World::simulate(self.worlds[i].see_brain().to_owned())) + // .collect::>(); while new_worlds.len() < self.size { - let rands = (gen_range(0, total + 1), gen_range(0, total + 1)); - let mut sum = 0; + let rands = (gen_range(0., total), gen_range(0., total)); + let mut sum = 0.; let (mut a, mut b) = (None, None); for world in &self.worlds { - sum += world.score; + sum += world.fitness(); if sum >= rands.0 { a = Some(world.see_brain()); } diff --git a/src/world.rs b/src/world.rs index 7001192..f1487ff 100644 --- a/src/world.rs +++ b/src/world.rs @@ -35,6 +35,16 @@ impl World { self.player.brain.as_ref().unwrap() } + pub fn fitness(&self) -> f32 { + self.score as f32 + + self.player.lifespan as f32 * 0.01 + + if self.player.shots > 0 { + self.score as f32 / self.player.shots as f32 * 10. + } else { + 0. + } + } + pub fn update(&mut self) { self.player.update(); let mut to_add: Vec = Vec::new();