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,
omega: f32,
pub alive: bool,
pub color: Color,
}
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. },
rot: 0.,
alive: true,
color: Color::new(1., 1., 1., 0.2),
}
}
@ -91,8 +93,7 @@ impl Asteroid {
AsteroidSize::Medium => 1.2,
AsteroidSize::Small => 0.8,
},
// WHITE,
Color::new(1., 1., 1., 0.4),
self.color,
);
}
}

View File

@ -128,7 +128,9 @@ async fn main() {
set_camera(&gamecam);
if is_key_pressed(KeyCode::S) {
speedup = (speedup * 10) % 9999;
println!("Speedup: {}", speedup);
}
if is_key_pressed(KeyCode::P) {
paused = !paused;
}
if !paused {
for _ in 0..speedup {
@ -165,6 +167,20 @@ async fn main() {
screen_width() - WIDTH - 3. * th,
(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_height = (screen_height() - 3. * th) * 0.5;
@ -216,20 +232,22 @@ async fn main() {
widgets::Group::new(hash!(), Vec2::new(100., ui_thick))
.position(Vec2::new(140., 0.))
.ui(ui, |ui| {
ui.drag(hash!(), "", Some((1, 500)), &mut size);
ui.drag(hash!(), "", Some((1, 300)), &mut size);
});
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.);
if widgets::Button::new(if bias { "Hide Bias" } else { "Show Bias" }).ui(ui)
{
bias = !bias;
};
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)
{
pop.best = !pop.best;
pop.focus = !pop.focus;
};
ui.same_line(0.);
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_text("-ve", width * 0.45 + 20., height * 0.45 + 10., 20., WHITE);
draw_rectangle(width * 0.45, height * 0.45 + 20., 10., 10., WHITE);
draw_text("+ve", width * 0.45 + 20., height * 0.45 + 30., 20., WHITE);
draw_rectangle(width * 0.47, height * 0.47, 10., 10., RED);
let params = TextParams {
font_size: 40,
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 {

View File

@ -19,7 +19,6 @@ pub struct Player {
last_shot: u8,
shot_interval: u8,
pub brain: Option<NN>,
debug: bool,
alive: bool,
pub color: Option<Color>,
pub lifespan: u32,
@ -36,7 +35,6 @@ impl Player {
drag: 0.001,
shot_interval: 18,
alive: true,
debug: false,
shots: 4,
outputs: vec![0.; 4],
@ -147,18 +145,21 @@ impl Player {
}
}
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.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.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;
}
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 {
self.last_shot = 0;
self.shots += 1;
@ -170,12 +171,12 @@ impl Player {
}
}
if is_key_pressed(KeyCode::D) {
self.debug = !self.debug;
}
if is_key_pressed(KeyCode::S) {
self.debug = false;
}
// 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;
@ -191,14 +192,11 @@ impl Player {
}
self.bullets
.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_data.clear();
}
pub fn draw(&self) {
pub fn draw(&self, debug: bool) {
let color = match self.color {
Some(c) => c,
// None => WHITE,
@ -218,14 +216,14 @@ impl Player {
if self.acc > 0. && gen_range(0., 1.) < 0.4 {
draw_triangle_lines(p6, p7, p8, 2., color);
}
if self.debug {
if debug {
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
// + self.dir.rotate(Vec2::from_angle(self.asteroid_data[0].1))
// * self.asteroid_data[0].0
// * 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
@ -244,7 +242,7 @@ impl Player {
}
for bullet in &self.bullets {
bullet.draw();
bullet.draw(color);
}
}
@ -265,7 +263,7 @@ impl Bullet {
fn update(&mut self) {
self.pos += self.vel;
}
fn draw(&self) {
draw_circle(self.pos.x, self.pos.y, 2., WHITE);
fn draw(&self, color: Color) {
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 {
size: usize,
pub gen: i32,
pub best: bool,
pub focus: bool,
pub debug: bool,
pub worlds: Vec<World>,
}
@ -32,27 +33,23 @@ impl Population {
self.next_gen();
}
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) {
for world in self.worlds.iter().rev() {
if self.best {
if world.player.color.is_some() {
world.draw();
if self.focus {
if world.track {
world.draw(self.debug);
}
} 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
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))
.map(|i| World::simulate(Some(self.worlds[i].see_brain().to_owned())))
.collect::<Vec<_>>();
new_worlds[0].set_best();
// new_worlds[0].export_brian();
new_worlds[0].track(true);
while new_worlds.len() < self.size {
let rands = (gen_range(0., total), gen_range(0., total));
let mut sum = 0.;

View File

@ -12,6 +12,7 @@ pub struct World {
pub score: f32,
pub over: bool,
pub fitness: f32,
pub track: bool,
}
impl World {
@ -30,8 +31,15 @@ impl World {
}
}
pub fn set_best(&mut self) {
self.player.color = Some(RED);
pub fn track(&mut self, track: bool) {
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 {
@ -44,6 +52,7 @@ impl World {
}
pub fn update(&mut self) {
self.player.update();
let mut to_add: Vec<Asteroid> = Vec::new();
for asteroid in &mut self.asteroids {
asteroid.update();
@ -85,7 +94,6 @@ impl World {
}
self.fitness =
(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.retain(|asteroid| asteroid.alive);
// if self.asteroids.iter().fold(0, |acc, x| {
@ -103,8 +111,8 @@ impl World {
}
}
pub fn draw(&self) {
self.player.draw();
pub fn draw(&self, debug: bool) {
self.player.draw(debug);
for asteroid in &self.asteroids {
asteroid.draw();
}
@ -156,33 +164,38 @@ impl World {
draw_circle(l1.x, l1.y, 5., WHITE);
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" },
-width * 0.5 + 20.,
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),
-width * 0.5 + 20.,
90.,
24.,
WHITE,
params,
);
draw_text(
draw_text_ex(
&format!("Fired: {}", self.player.shots),
-width * 0.5 + 20.,
110.,
24.,
WHITE,
params,
);
draw_text(
draw_text_ex(
&format!("Fitness: {:.2}", self.fitness),
-width * 0.5 + 20.,
130.,
24.,
WHITE,
params,
);
}
}