debug, selection

This commit is contained in:
sparshg 2023-01-10 00:55:18 +05:30
parent 7110d063b4
commit b9bc8ae08d
6 changed files with 96 additions and 65 deletions

View File

@ -17,6 +17,7 @@ pub struct Asteroid {
rot: f32, rot: f32,
omega: f32, omega: f32,
pub alive: bool, pub alive: bool,
pub color: Color,
} }
impl Asteroid { impl Asteroid {
@ -47,6 +48,7 @@ impl Asteroid {
omega: gen_range(0.8, 3.5) * if gen_range(0., 1.) > 0.5 { -1. } else { 1. }, omega: gen_range(0.8, 3.5) * if gen_range(0., 1.) > 0.5 { -1. } else { 1. },
rot: 0., rot: 0.,
alive: true, alive: true,
color: Color::new(1., 1., 1., 0.2),
} }
} }
@ -91,8 +93,7 @@ impl Asteroid {
AsteroidSize::Medium => 1.2, AsteroidSize::Medium => 1.2,
AsteroidSize::Small => 0.8, AsteroidSize::Small => 0.8,
}, },
// WHITE, self.color,
Color::new(1., 1., 1., 0.4),
); );
} }
} }

View File

@ -128,7 +128,9 @@ async fn main() {
set_camera(&gamecam); set_camera(&gamecam);
if is_key_pressed(KeyCode::S) { if is_key_pressed(KeyCode::S) {
speedup = (speedup * 10) % 9999; speedup = (speedup * 10) % 9999;
println!("Speedup: {}", speedup); }
if is_key_pressed(KeyCode::P) {
paused = !paused;
} }
if !paused { if !paused {
for _ in 0..speedup { for _ in 0..speedup {
@ -165,6 +167,20 @@ async fn main() {
screen_width() - WIDTH - 3. * th, screen_width() - WIDTH - 3. * th,
(screen_height() - 7. * th) * 0.5 - 2. * ui_thick, (screen_height() - 7. * th) * 0.5 - 2. * ui_thick,
); );
if is_mouse_button_pressed(MouseButton::Left) && mouse_position().0 < WIDTH + th {
let (x, y) = mouse_position();
for i in 0..pop.worlds.len() {
if (pop.worlds[i].player.pos - vec2(x - th - WIDTH * 0.5, y - th - HEIGHT * 0.5))
.length_squared()
< 256.
{
pop.worlds.swap(0, i);
pop.worlds[0].track(true);
pop.worlds[i].track(false);
break;
}
}
}
let ui_width = screen_width() - WIDTH - 3. * th + 1.; let ui_width = screen_width() - WIDTH - 3. * th + 1.;
let ui_height = (screen_height() - 3. * th) * 0.5; let ui_height = (screen_height() - 3. * th) * 0.5;
@ -216,20 +232,22 @@ async fn main() {
widgets::Group::new(hash!(), Vec2::new(100., ui_thick)) widgets::Group::new(hash!(), Vec2::new(100., ui_thick))
.position(Vec2::new(140., 0.)) .position(Vec2::new(140., 0.))
.ui(ui, |ui| { .ui(ui, |ui| {
ui.drag(hash!(), "", Some((1, 500)), &mut size); ui.drag(hash!(), "", Some((1, 300)), &mut size);
}); });
ui.same_line(307.); ui.same_line(307.);
widgets::Button::new("Debug").ui(ui); if widgets::Button::new("Debug").ui(ui) {
pop.debug = !pop.debug;
};
ui.same_line(0.); ui.same_line(0.);
if widgets::Button::new(if bias { "Hide Bias" } else { "Show Bias" }).ui(ui) if widgets::Button::new(if bias { "Hide Bias" } else { "Show Bias" }).ui(ui)
{ {
bias = !bias; bias = !bias;
}; };
ui.same_line(0.); ui.same_line(0.);
if widgets::Button::new(if !pop.best { "Show Best" } else { "Show All " }) if widgets::Button::new(if !pop.focus { "Show Best" } else { "Show All " })
.ui(ui) .ui(ui)
{ {
pop.best = !pop.best; pop.focus = !pop.focus;
}; };
ui.same_line(0.); ui.same_line(0.);
if widgets::Button::new(restart).ui(ui) { if widgets::Button::new(restart).ui(ui) {

View File

@ -184,10 +184,15 @@ impl NN {
); );
} }
} }
draw_rectangle(width * 0.45, height * 0.45, 10., 10., RED); draw_rectangle(width * 0.47, height * 0.47, 10., 10., RED);
draw_text("-ve", width * 0.45 + 20., height * 0.45 + 10., 20., WHITE); let params = TextParams {
draw_rectangle(width * 0.45, height * 0.45 + 20., 10., 10., WHITE); font_size: 40,
draw_text("+ve", width * 0.45 + 20., height * 0.45 + 30., 20., WHITE); font_scale: 0.5,
..Default::default()
};
draw_text_ex("-ve", width * 0.47 + 20., height * 0.47 + 10., params);
draw_rectangle(width * 0.47, height * 0.47 + 20., 10., 10., WHITE);
draw_text_ex("+ve", width * 0.47 + 20., height * 0.47 + 30., params);
} }
pub fn export(&self) -> String { pub fn export(&self) -> String {

View File

@ -19,7 +19,6 @@ pub struct Player {
last_shot: u8, last_shot: u8,
shot_interval: u8, shot_interval: u8,
pub brain: Option<NN>, pub brain: Option<NN>,
debug: bool,
alive: bool, alive: bool,
pub color: Option<Color>, pub color: Option<Color>,
pub lifespan: u32, pub lifespan: u32,
@ -36,7 +35,6 @@ impl Player {
drag: 0.001, drag: 0.001,
shot_interval: 18, shot_interval: 18,
alive: true, alive: true,
debug: false,
shots: 4, shots: 4,
outputs: vec![0.; 4], outputs: vec![0.; 4],
@ -147,18 +145,21 @@ impl Player {
} }
} }
let keys: Vec<bool> = self.outputs.iter().map(|&x| x > 0.).collect(); let keys: Vec<bool> = self.outputs.iter().map(|&x| x > 0.).collect();
if is_key_down(KeyCode::Right) && self.debug || keys[0] { if keys[0] {
// RIGHT
self.rot = (self.rot + 0.1 + TAU as f32) % TAU as f32; self.rot = (self.rot + 0.1 + TAU as f32) % TAU as f32;
self.dir = vec2(self.rot.cos(), self.rot.sin()); self.dir = vec2(self.rot.cos(), self.rot.sin());
} }
if is_key_down(KeyCode::Left) && self.debug || keys[1] { if keys[1] {
// LEFT
self.rot = (self.rot - 0.1 + TAU as f32) % TAU as f32; self.rot = (self.rot - 0.1 + TAU as f32) % TAU as f32;
self.dir = vec2(self.rot.cos(), self.rot.sin()); self.dir = vec2(self.rot.cos(), self.rot.sin());
} }
if is_key_down(KeyCode::Up) && self.debug || keys[2] { if is_key_down(KeyCode::Up) || keys[2] {
// THROTTLE
self.acc = 0.14; self.acc = 0.14;
} }
if is_key_down(KeyCode::Space) && self.debug || keys[3] { if is_key_down(KeyCode::Space) || keys[3] {
if self.last_shot > self.shot_interval { if self.last_shot > self.shot_interval {
self.last_shot = 0; self.last_shot = 0;
self.shots += 1; self.shots += 1;
@ -170,12 +171,12 @@ impl Player {
} }
} }
if is_key_pressed(KeyCode::D) { // if is_key_pressed(KeyCode::D) {
self.debug = !self.debug; // self.debug = !self.debug;
} // }
if is_key_pressed(KeyCode::S) { // if is_key_pressed(KeyCode::S) {
self.debug = false; // self.debug = false;
} // }
self.vel += self.acc * self.dir - self.drag * self.vel.length() * self.vel; self.vel += self.acc * self.dir - self.drag * self.vel.length() * self.vel;
self.pos += self.vel; self.pos += self.vel;
@ -191,14 +192,11 @@ impl Player {
} }
self.bullets self.bullets
.retain(|b| b.alive && b.pos.x.abs() * 2. < WIDTH && b.pos.y.abs() * 2. < HEIGHT); .retain(|b| b.alive && b.pos.x.abs() * 2. < WIDTH && b.pos.y.abs() * 2. < HEIGHT);
if self.debug {
self.draw();
}
self.asteroid = None; self.asteroid = None;
// self.asteroid_data.clear(); // self.asteroid_data.clear();
} }
pub fn draw(&self) { pub fn draw(&self, debug: bool) {
let color = match self.color { let color = match self.color {
Some(c) => c, Some(c) => c,
// None => WHITE, // None => WHITE,
@ -218,14 +216,14 @@ impl Player {
if self.acc > 0. && gen_range(0., 1.) < 0.4 { if self.acc > 0. && gen_range(0., 1.) < 0.4 {
draw_triangle_lines(p6, p7, p8, 2., color); draw_triangle_lines(p6, p7, p8, 2., color);
} }
if self.debug { if debug {
if let Some(ast) = self.asteroid.as_ref() { if let Some(ast) = self.asteroid.as_ref() {
draw_circle_lines(ast.pos.x, ast.pos.y, ast.radius, 1., GRAY); draw_circle_lines(ast.pos.x, ast.pos.y, ast.radius, 1., DARKBLUE);
// let p = self.pos // let p = self.pos
// + self.dir.rotate(Vec2::from_angle(self.asteroid_data[0].1)) // + self.dir.rotate(Vec2::from_angle(self.asteroid_data[0].1))
// * self.asteroid_data[0].0 // * self.asteroid_data[0].0
// * WIDTH; // * WIDTH;
draw_line(self.pos.x, self.pos.y, ast.pos.x, ast.pos.y, 1., GRAY); draw_line(self.pos.x, self.pos.y, ast.pos.x, ast.pos.y, 1., DARKBLUE);
} }
// Draw raycasts // Draw raycasts
@ -244,7 +242,7 @@ impl Player {
} }
for bullet in &self.bullets { for bullet in &self.bullets {
bullet.draw(); bullet.draw(color);
} }
} }
@ -265,7 +263,7 @@ impl Bullet {
fn update(&mut self) { fn update(&mut self) {
self.pos += self.vel; self.pos += self.vel;
} }
fn draw(&self) { fn draw(&self, color: Color) {
draw_circle(self.pos.x, self.pos.y, 2., WHITE); draw_circle(self.pos.x, self.pos.y, 2., color);
} }
} }

View File

@ -6,7 +6,8 @@ use crate::{nn::NN, world::World, HEIGHT, WIDTH};
pub struct Population { pub struct Population {
size: usize, size: usize,
pub gen: i32, pub gen: i32,
pub best: bool, pub focus: bool,
pub debug: bool,
pub worlds: Vec<World>, pub worlds: Vec<World>,
} }
@ -32,27 +33,23 @@ impl Population {
self.next_gen(); self.next_gen();
} }
if is_key_pressed(KeyCode::Z) { if is_key_pressed(KeyCode::Z) {
self.best = !self.best; self.focus = !self.focus;
}
if is_key_pressed(KeyCode::D) {
self.debug = !self.debug;
} }
} }
pub fn draw(&self) { pub fn draw(&self) {
for world in self.worlds.iter().rev() { for world in self.worlds.iter().rev() {
if self.best { if self.focus {
if world.player.color.is_some() { if world.track {
world.draw(); world.draw(self.debug);
} }
} else if !world.over { } else if !world.over {
world.draw(); world.draw(self.debug);
} }
} }
// draw_text(
// &format!("Gen: {}", self.gen),
// -150. + WIDTH * 0.5,
// 30. - HEIGHT * 0.5,
// 32.,
// WHITE,
// );
// draw black background outside the screen // draw black background outside the screen
let th = (screen_height() - HEIGHT) * 0.5; let th = (screen_height() - HEIGHT) * 0.5;
@ -85,8 +82,7 @@ impl Population {
let mut new_worlds = (0..std::cmp::max(1, self.size / 20)) let mut new_worlds = (0..std::cmp::max(1, self.size / 20))
.map(|i| World::simulate(Some(self.worlds[i].see_brain().to_owned()))) .map(|i| World::simulate(Some(self.worlds[i].see_brain().to_owned())))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
new_worlds[0].set_best(); new_worlds[0].track(true);
// new_worlds[0].export_brian();
while new_worlds.len() < self.size { while new_worlds.len() < self.size {
let rands = (gen_range(0., total), gen_range(0., total)); let rands = (gen_range(0., total), gen_range(0., total));
let mut sum = 0.; let mut sum = 0.;

View File

@ -12,6 +12,7 @@ pub struct World {
pub score: f32, pub score: f32,
pub over: bool, pub over: bool,
pub fitness: f32, pub fitness: f32,
pub track: bool,
} }
impl World { impl World {
@ -30,8 +31,15 @@ impl World {
} }
} }
pub fn set_best(&mut self) { pub fn track(&mut self, track: bool) {
self.player.color = Some(RED); self.player.color = if track { Some(RED) } else { None };
for asteroid in &mut self.asteroids {
asteroid.color = if track {
Color::new(1., 0., 0., 0.8)
} else {
Color::new(1., 1., 1., 0.2)
};
}
} }
pub fn see_brain(&self) -> &NN { pub fn see_brain(&self) -> &NN {
@ -44,6 +52,7 @@ impl World {
} }
pub fn update(&mut self) { pub fn update(&mut self) {
self.player.update();
let mut to_add: Vec<Asteroid> = Vec::new(); let mut to_add: Vec<Asteroid> = Vec::new();
for asteroid in &mut self.asteroids { for asteroid in &mut self.asteroids {
asteroid.update(); asteroid.update();
@ -85,7 +94,6 @@ impl World {
} }
self.fitness = self.fitness =
(self.score / self.player.shots as f32).powi(2) * self.player.lifespan as f32; (self.score / self.player.shots as f32).powi(2) * self.player.lifespan as f32;
self.player.update();
self.asteroids.append(&mut to_add); self.asteroids.append(&mut to_add);
self.asteroids.retain(|asteroid| asteroid.alive); self.asteroids.retain(|asteroid| asteroid.alive);
// if self.asteroids.iter().fold(0, |acc, x| { // if self.asteroids.iter().fold(0, |acc, x| {
@ -103,8 +111,8 @@ impl World {
} }
} }
pub fn draw(&self) { pub fn draw(&self, debug: bool) {
self.player.draw(); self.player.draw(debug);
for asteroid in &self.asteroids { for asteroid in &self.asteroids {
asteroid.draw(); asteroid.draw();
} }
@ -156,33 +164,38 @@ impl World {
draw_circle(l1.x, l1.y, 5., WHITE); draw_circle(l1.x, l1.y, 5., WHITE);
draw_circle(l1.x, l1.y, 3.5, BLACK); draw_circle(l1.x, l1.y, 3.5, BLACK);
} }
draw_text( let params = TextParams {
font_size: 48,
font_scale: 0.5,
..Default::default()
};
draw_text_ex(
if self.over { "DEAD" } else { "ALIVE" }, if self.over { "DEAD" } else { "ALIVE" },
-width * 0.5 + 20., -width * 0.5 + 20.,
70., 70.,
24., {
if self.over { RED } else { GREEN }, let mut p = params.clone();
p.color = if self.over { RED } else { GREEN };
p
},
); );
draw_text( draw_text_ex(
&format!("Hits: {}", self.score), &format!("Hits: {}", self.score),
-width * 0.5 + 20., -width * 0.5 + 20.,
90., 90.,
24., params,
WHITE,
); );
draw_text( draw_text_ex(
&format!("Fired: {}", self.player.shots), &format!("Fired: {}", self.player.shots),
-width * 0.5 + 20., -width * 0.5 + 20.,
110., 110.,
24., params,
WHITE,
); );
draw_text( draw_text_ex(
&format!("Fitness: {:.2}", self.fitness), &format!("Fitness: {:.2}", self.fitness),
-width * 0.5 + 20., -width * 0.5 + 20.,
130., 130.,
24., params,
WHITE,
); );
} }
} }