fixed bugs
This commit is contained in:
parent
666c9a8b8e
commit
db2df770c6
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'yourprogram'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--lib",
|
||||
"--package=yourprogram"
|
||||
],
|
||||
"filter": {
|
||||
"name": "yourprogram",
|
||||
"kind": "lib"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -89,7 +89,7 @@ impl Asteroid {
|
|||
AsteroidSize::Medium => 1.2,
|
||||
AsteroidSize::Small => 0.8,
|
||||
},
|
||||
Color::new(1., 1., 1., 0.5),
|
||||
Color::new(1., 1., 1., 0.4),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,11 @@ async fn main() {
|
|||
..Default::default()
|
||||
};
|
||||
set_camera(&cam);
|
||||
let mut pop = Population::new(100);
|
||||
let mut pop = Population::new(10);
|
||||
let mut speedup = false;
|
||||
// for _ in 0..100000 * 5 {
|
||||
// pop.update();
|
||||
// }
|
||||
loop {
|
||||
clear_background(BLACK);
|
||||
if is_key_pressed(KeyCode::S) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use macroquad::rand::gen_range;
|
||||
use nalgebra::*;
|
||||
use r::Rng;
|
||||
use rand_distr::StandardNormal;
|
||||
|
@ -10,10 +11,10 @@ enum ActivationFunc {
|
|||
ReLU,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NN {
|
||||
pub config: Vec<usize>,
|
||||
weights: Vec<DMatrix<f32>>,
|
||||
pub weights: Vec<DMatrix<f32>>,
|
||||
activ_func: ActivationFunc,
|
||||
mut_rate: f32,
|
||||
}
|
||||
|
@ -63,8 +64,8 @@ impl NN {
|
|||
pub fn mutate(&mut self) {
|
||||
for weight in &mut self.weights {
|
||||
for ele in weight {
|
||||
if r::random() {
|
||||
*ele = r::thread_rng().sample::<f32, StandardNormal>(StandardNormal) * 0.05;
|
||||
if gen_range(0., 1.) < 0.05 {
|
||||
*ele = r::thread_rng().sample::<f32, StandardNormal>(StandardNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ impl Player {
|
|||
pub fn simulate(brain: NN, max_asteroids: usize) -> Self {
|
||||
assert_eq!(
|
||||
brain.config[0] - 1,
|
||||
max_asteroids + 5,
|
||||
max_asteroids * 3 + 5,
|
||||
"NN input size must match max_asteroids"
|
||||
);
|
||||
let mut p = Player::new();
|
||||
|
@ -77,8 +77,7 @@ impl Player {
|
|||
self.lifespan += 1;
|
||||
let mut mag = 0.;
|
||||
let mut keys = vec![false, false, false, false];
|
||||
|
||||
self.asteroids_data.resize(self.max_asteroids, 0.);
|
||||
self.asteroids_data.resize(self.max_asteroids * 3, 0.);
|
||||
let mut inputs = vec![
|
||||
self.pos.x / screen_width() + 0.5,
|
||||
self.pos.y / screen_height() + 0.5,
|
||||
|
@ -124,10 +123,10 @@ impl Player {
|
|||
|
||||
self.vel += mag * self.dir - self.drag * self.vel.length() * self.vel;
|
||||
self.pos += self.vel;
|
||||
if self.pos.x.abs() > screen_width() / 2. + 10. {
|
||||
if self.pos.x.abs() > screen_width() * 0.5 + 10. {
|
||||
self.pos.x *= -1.;
|
||||
}
|
||||
if self.pos.y.abs() > screen_height() / 2. + 10. {
|
||||
if self.pos.y.abs() > screen_height() * 0.5 + 10. {
|
||||
self.pos.y *= -1.;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ impl Population {
|
|||
Self {
|
||||
size,
|
||||
worlds: (0..size)
|
||||
.map(|_| World::simulate(NN::new(vec![33, 16, 4])))
|
||||
.map(|_| World::simulate(NN::new(vec![89, 16, 4])))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -52,26 +52,38 @@ impl Population {
|
|||
|
||||
pub fn next_gen(&mut self) {
|
||||
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::<Vec<_>>();
|
||||
self.worlds
|
||||
.sort_by(|a, b| b.fitness().partial_cmp(&a.fitness()).unwrap());
|
||||
let mut new_worlds = (0..self.size / 10)
|
||||
.map(|i| World::simulate(self.worlds[i].see_brain().to_owned()))
|
||||
.collect::<Vec<_>>();
|
||||
// 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);
|
||||
let mut sum = 0.;
|
||||
let (mut a, mut b) = (None, None);
|
||||
for world in &self.worlds {
|
||||
sum += world.fitness();
|
||||
if sum >= rands.0 {
|
||||
if a.is_none() && sum >= rands.0 {
|
||||
a = Some(world.see_brain());
|
||||
}
|
||||
if sum >= rands.1 {
|
||||
if b.is_none() && sum >= rands.1 {
|
||||
b = Some(world.see_brain());
|
||||
}
|
||||
}
|
||||
// println!("{}", &a.unwrap().weights[0]);
|
||||
// println!("{}", &b.unwrap().weights[0]);
|
||||
let mut new_brain = NN::crossover(a.unwrap(), b.unwrap());
|
||||
// println!("{}", &a.unwrap().weights[0]);
|
||||
// println!("{}", &b.unwrap().weights[0]);
|
||||
// println!("{}", &new_brain.weights[0]);
|
||||
new_brain.mutate();
|
||||
new_worlds.push(World::simulate(new_brain));
|
||||
}
|
||||
|
|
22
src/world.rs
22
src/world.rs
|
@ -36,12 +36,24 @@ impl World {
|
|||
}
|
||||
|
||||
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.
|
||||
// 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.
|
||||
// }
|
||||
// );
|
||||
(self.score + 1) as f32
|
||||
* 10.
|
||||
* self.player.lifespan as f32
|
||||
* if self.player.shots > 0 {
|
||||
(self.score as f32 / self.player.shots as f32)
|
||||
* (self.score as f32 / self.player.shots as f32)
|
||||
} else {
|
||||
0.
|
||||
1.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue