debug, selection
This commit is contained in:
parent
7110d063b4
commit
b9bc8ae08d
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -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) {
|
||||
|
|
13
src/nn.rs
13
src/nn.rs
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.;
|
||||
|
|
47
src/world.rs
47
src/world.rs
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue