Skip to content

Commit

Permalink
name neuroevolution example and comment
Browse files Browse the repository at this point in the history
  • Loading branch information
shiffman committed Apr 15, 2020
1 parent a18ea8d commit 1e6c009
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Daniel Shiffman
// Neuro-Evolution Flappy Bird with TensorFlow.js
// http:https://thecodingtrain.com
// https://youtu.be/cdUNkwXx-I4
// Neuro-Evolution Flappy Bird with ml5.js

// Bird class

class Bird {
constructor(brain) {
Expand All @@ -14,9 +14,12 @@ class Bird {

this.score = 0;
this.fitness = 0;

// Bird can be created with an existing neural network
if (brain) {
this.brain = brain;
} else {
// Create a new neural network
const options = {
inputs: 5,
outputs: ['up', 'down'],
Expand All @@ -37,7 +40,9 @@ class Bird {
this.velocity += this.lift;
}

// Mutate the brain
mutate() {
// 10% mutation rate
this.brain.mutate(0.1);
}

Expand All @@ -53,12 +58,15 @@ class Bird {
}
}

// Normalize 5 inputs
let inputs = [];
inputs[0] = this.y / height;
inputs[1] = closest.top / height;
inputs[2] = closest.bottom / height;
inputs[3] = closest.x / width;
inputs[4] = this.velocity / 10;

// Jump according to neural network output
const results = this.brain.classifySync(inputs);
if (results[0].label === 'up') {
this.up();
Expand All @@ -70,10 +78,9 @@ class Bird {
}

update() {
// Score increases each frame
this.score++;

this.velocity += this.gravity;
//this.velocity *= 0.9;
this.y += this.velocity;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
// Daniel Shiffman
// Neuro-Evolution Flappy Bird
// Neuro-Evolution Flappy Bird with ml5.js

// Genetic Algorithm Functions
// TODO: create a ml5.population() class to manage this?

// Create the next generation
function nextGeneration() {
console.log('next generation');
console.log('next generation');
// Calculate fitness values
calculateFitness();

// Create a new population
// Create new population of birds
for (let i = 0; i < TOTAL; i++) {
birds[i] = reproduce();
}
Expand All @@ -14,9 +19,11 @@ function nextGeneration() {
for (let i = 0; i < TOTAL; i++) {
savedBirds[i].brain.dispose();
}
// Clear the array
savedBirds = [];
}

// Create a child bird from two parents
function reproduce() {
let brainA = pickOne();
let brainB = pickOne();
Expand All @@ -25,6 +32,7 @@ function reproduce() {
return new Bird(childBrain);
}

// Pick one parent probability according to normalized fitness
function pickOne() {
let index = 0;
let r = random(1);
Expand All @@ -37,6 +45,7 @@ function pickOne() {
return bird.brain;
}

// Normalize all fitness values
function calculateFitness() {
let sum = 0;
for (let bird of savedBirds) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Daniel Shiffman
// Neuro-Evolution Flappy Bird with TensorFlow.js
// http:https://thecodingtrain.com
// https://youtu.be/cdUNkwXx-I4
// Neuro-Evolution Flappy Bird

// Class for a Pipe

class Pipe {
constructor() {
// Fixed spacing
this.spacing = 125;
this.top = random(height / 6, (3 / 4) * height);
this.bottom = height - (this.top + this.spacing);
Expand Down Expand Up @@ -34,10 +35,6 @@ class Pipe {
}

offscreen() {
if (this.x < -this.w) {
return true;
} else {
return false;
}
return (this.x < -this.w);
}
}
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
// Daniel Shiffman
// Neuro-Evolution Flappy Bird with TensorFlow.js
// http:https://thecodingtrain.com
// https://youtu.be/cdUNkwXx-I4
// Neuro-Evolution Flappy Bird with ml5.js

const TOTAL = 100;
// Current birds
let birds = [];
// Save any birds that die
let savedBirds = [];
let pipes = [];
let counter = 0;
let slider;

function keyPressed() {
if (key === 'S') {
let bird = birds[0];
saveJSON(bird.brain, 'bird.json');
}
}

function setup() {
createCanvas(640, 480);
// Improves performance for small neural networks and classifySync()
ml5.tf.setBackend('cpu');

// Slider for speeding up simulation
slider = createSlider(1, 10, 1);

// Create initial population of birds
for (let i = 0; i < TOTAL; i++) {
birds[i] = new Bird();
}
}

function draw() {
// Speed up simulation
for (let n = 0; n < slider.value(); n++) {
// new pipes every N frames
if (counter % 75 == 0) {
pipes.push(new Pipe());
}
counter++;

// Run game
for (let i = pipes.length - 1; i >= 0; i--) {
pipes[i].update();

for (let j = birds.length - 1; j >= 0; j--) {
if (pipes[i].hits(birds[j])) {
// Save bird if it dies
savedBirds.push(birds.splice(j, 1)[0]);
}
}

// Remove pipes when they leave
if (pipes[i].offscreen()) {
pipes.splice(i, 1);
}
}

// Remove / save any birds that go offscreen
for (let i = birds.length - 1; i >= 0; i--) {
if (birds[i].offScreen()) {
savedBirds.push(birds.splice(i, 1)[0]);
}
}

// Run all birds
for (let bird of birds) {
bird.think(pipes);
bird.update();
}

// If all the birds have died go to the next generation
if (birds.length === 0) {
counter = 0;
nextGeneration();
Expand All @@ -75,11 +81,4 @@ function draw() {
for (let pipe of pipes) {
pipe.show();
}
}

// function keyPressed() {
// if (key == ' ') {
// bird.up();
// //console.log("SPACE");
// }
// }
}

0 comments on commit 1e6c009

Please sign in to comment.