# Flappy birds notepad++ javascript

**URL:** <https://discourse.processing.org/t/flappy-birds-notepad-javascript/1975>\
**Category:** Coding Questions\
**Created:** [July 21, 2018, 11:50pm UTC](https://discourse.processing.org/t/flappy-birds-notepad-javascript/1975 "2018-07-21T23:50:47Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ctrembla](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@ctrembla](https://discourse.processing.org/u/ctrembla)\
**Post date:** [July 21, 2018, 11:50pm UTC](https://discourse.processing.org/t/flappy-birds-notepad-javascript/1975/1 "2018-07-21T23:50:47Z")

</div>

OK, i’m making flappy birds using notepad ++ javascript.

[![](https://img.youtube.com/vi/c6y21FkaUqw/maxresdefault.jpg "Coding Challenge #100: Neuroevolution Flappy Bird - Part 1") ](https://www.youtube.com/watch?v=c6y21FkaUqw&t=5s)

I was following along with this tutorial after adding the files from his neural network videos and when he tested his program mine didn’t work. I checked the error and it pointed to bird.7 or however that error writes it. I checked the line and saw it was written the same as how the video has it. I cant figure out whats wrong with my program and why it not doing the same as in the video.  
here sketch

```auto
var bird;
var pipes = [];
var score = 0;
function setup(){
	createCanvas(400,600);
	bird = new Bird();
	pipes.push(new Pipe());
}
function draw(){
	background(0);
	bird.think();
	bird.show();
	bird.move();
	text(score,10,10);
	if (frameCount % 300 == 0){
		pipes.push(new Pipe());
	}
	for (var i = pipes.length-1; i >= 0; i--){
		pipes[i].show();
		pipes[i].update();
		if (pipes[i].x < -pipes[i].w){
			pipes.splice(i,1);
			score += 1;
		}
		if (pipes[i].hits(bird)){
			console.log("Collide");
		}
	}
}

```

here bird

```auto
function Bird(){
		this.y = height/2;
		this.x = 50;
		this.grav = 0.6;
		this.vel = 0;
		this.lift = -15;
		this.brain = new NeuralNetwork(4,4,1);// here where it say error
	this.show = function() {
		fill(255);
		ellipse(this.x,this.y,32,32);
	}
	
	this.up = function(){
		this.vel += this.lift;
	}
	think() = function(){
		let input = [1.0,0.5,0.2,0.3];
		let output = this.brain.predict(inputs);
		if (output > 0.5){
			this.up();
		}
	}
	this.move = function(){
		this.vel += this.grav;
		this.vel *= 0.9;
		this.y += this.vel;
		if (this.y > height) {
			this.y = height;
			this.vel = 0;
		}
		if (this.y < 0) {
			this.y = 0;
			this.vel = 0;
		}
	}
}

```

here pipes

```auto
function Pipe() {
	var spacing = 75;
	var centery = random(spacing,height-spacing);
	this.top = centery - spacing/2;
	this.bottom = height - (centery + spacing/2);
	this.x = width;
	this.w = 20;
	this.speed = 1;
	this.c = 0;
	this.highlight = false;
	
	this.hits = function(bird){
		if (bird.y < this.top || bird.y > height - this.bottom){
			if (bird.x > this.x && bird.x < this.x + this.w){
				this.highlight = true;
				return true;
			}
		}
		this.highlight = false;
		return false;
	}
	this.show = function(){
		fill(255);
		if (this.highlight){
			fill(255,0,0);
		}
		rect(this.x, 0, this.w, this.top);
		rect(this.x, height-this.bottom, this.w, this.bottom);
	}
	
	this.update = function(){
		this.x -= this.speed;
	}
}

```

here nn

```auto
class ActivationFunction {
  constructor(func, dfunc) {
    this.func = func;
    this.dfunc = dfunc;
  }
}

let sigmoid = new ActivationFunction(
  x => 1 / (1 + Math.exp(-x)),
  y => y * (1 - y)
);

let tanh = new ActivationFunction(
  x => Math.tanh(x),
  y => 1 - (y * y)
);

class NeuralNetwork {
  // TODO: document what a, b, c are
  constructor(a, b, c) {
    if (a instanceof NeuralNetwork) {
      this.input_nodes = a.input_nodes;
      this.hidden_nodes = a.hidden_nodes;
      this.output_nodes = a.output_nodes;

      this.weights_ih = a.weights_ih.copy();
      this.weights_ho = a.weights_ho.copy();

      this.bias_h = a.bias_h.copy();
      this.bias_o = a.bias_o.copy();
    } else {
      this.input_nodes = a;
      this.hidden_nodes = b;
      this.output_nodes = c;

      this.weights_ih = new Matrix(this.hidden_nodes, this.input_nodes);
      this.weights_ho = new Matrix(this.output_nodes, this.hidden_nodes);
      this.weights_ih.randomize();
      this.weights_ho.randomize();

      this.bias_h = new Matrix(this.hidden_nodes, 1);
      this.bias_o = new Matrix(this.output_nodes, 1);
      this.bias_h.randomize();
      this.bias_o.randomize();
    }

    // TODO: copy these as well
    this.setLearningRate();
    this.setActivationFunction();

  }

  predict(input_array) {

    // Generating the Hidden Outputs
    let inputs = Matrix.fromArray(input_array);
    let hidden = Matrix.multiply(this.weights_ih, inputs);
    hidden.add(this.bias_h);
    // activation function!
    hidden.map(this.activation_function.func);

    // Generating the output's output!
    let output = Matrix.multiply(this.weights_ho, hidden);
    output.add(this.bias_o);
    output.map(this.activation_function.func);

    // Sending back to the caller!
    return output.toArray();
  }

  setLearningRate(learning_rate = 0.1) {
    this.learning_rate = learning_rate;
  }

  setActivationFunction(func = sigmoid) {
    this.activation_function = func;
  }

  train(input_array, target_array) {
    // Generating the Hidden Outputs
    let inputs = Matrix.fromArray(input_array);
    let hidden = Matrix.multiply(this.weights_ih, inputs);
    hidden.add(this.bias_h);
    // activation function!
    hidden.map(this.activation_function.func);

    // Generating the output's output!
    let outputs = Matrix.multiply(this.weights_ho, hidden);
    outputs.add(this.bias_o);
    outputs.map(this.activation_function.func);

    // Convert array to matrix object
    let targets = Matrix.fromArray(target_array);

    // Calculate the error
    // ERROR = TARGETS - OUTPUTS
    let output_errors = Matrix.subtract(targets, outputs);

    // let gradient = outputs * (1 - outputs);
    // Calculate gradient
    let gradients = Matrix.map(outputs, this.activation_function.dfunc);
    gradients.multiply(output_errors);
    gradients.multiply(this.learning_rate);

    // Calculate deltas
    let hidden_T = Matrix.transpose(hidden);
    let weight_ho_deltas = Matrix.multiply(gradients, hidden_T);

    // Adjust the weights by deltas
    this.weights_ho.add(weight_ho_deltas);
    // Adjust the bias by its deltas (which is just the gradients)
    this.bias_o.add(gradients);

    // Calculate the hidden layer errors
    let who_t = Matrix.transpose(this.weights_ho);
    let hidden_errors = Matrix.multiply(who_t, output_errors);

    // Calculate hidden gradient
    let hidden_gradient = Matrix.map(hidden, this.activation_function.dfunc);
    hidden_gradient.multiply(hidden_errors);
    hidden_gradient.multiply(this.learning_rate);

    // Calcuate input->hidden deltas
    let inputs_T = Matrix.transpose(inputs);
    let weight_ih_deltas = Matrix.multiply(hidden_gradient, inputs_T);

    this.weights_ih.add(weight_ih_deltas);
    // Adjust the bias by its deltas (which is just the gradients)
    this.bias_h.add(hidden_gradient);

    // outputs.print();
    // targets.print();
    // error.print();
  }

  serialize() {
    return JSON.stringify(this);
  }

  static deserialize(data) {
    if (typeof data == 'string') {
      data = JSON.parse(data);
    }
    let nn = new NeuralNetwork(data.input_nodes, data.hidden_nodes, data.output_nodes);
    nn.weights_ih = Matrix.deserialize(data.weights_ih);
    nn.weights_ho = Matrix.deserialize(data.weights_ho);
    nn.bias_h = Matrix.deserialize(data.bias_h);
    nn.bias_o = Matrix.deserialize(data.bias_o);
    nn.learning_rate = data.learning_rate;
    return nn;
  }

  // Adding function for neuro-evolution
  copy() {
    return new NeuralNetwork(this);
  }

  // Accept an arbitrary function for mutation
  mutate(func) {
    this.weights_ih.map(func);
    this.weights_ho.map(func);
    this.bias_h.map(func);
    this.bias_o.map(func);
  }

}

```

here matrix

```auto
class Matrix {
  constructor(rows, cols) {
    this.rows = rows;
    this.cols = cols;
    this.data = Array(this.rows).fill().map(() => Array(this.cols).fill(0));
  }

  copy() {
    let m = new Matrix(this.rows, this.cols);
    for (let i = 0; i < this.rows; i++) {
      for (let j = 0; j < this.cols; j++) {
        m.data[i][j] = this.data[i][j];
      }
    }
    return m;
  }

  static fromArray(arr) {
    return new Matrix(arr.length, 1).map((e, i) => arr[i]);
  }

  static subtract(a, b) {
    if (a.rows !== b.rows || a.cols !== b.cols) {
      console.log('Columns and Rows of A must match Columns and Rows of B.');
      return;
    }

    // Return a new Matrix a-b
    return new Matrix(a.rows, a.cols)
      .map((_, i, j) => a.data[i][j] - b.data[i][j]);
  }

  toArray() {
    let arr = [];
    for (let i = 0; i < this.rows; i++) {
      for (let j = 0; j < this.cols; j++) {
        arr.push(this.data[i][j]);
      }
    }
    return arr;
  }

  randomize() {
    return this.map(e => Math.random() * 2 - 1);
  }

  add(n) {
    if (n instanceof Matrix) {
      if (this.rows !== n.rows || this.cols !== n.cols) {
        console.log('Columns and Rows of A must match Columns and Rows of B.');
        return;
      }
      return this.map((e, i, j) => e + n.data[i][j]);
    } else {
      return this.map(e => e + n);
    }
  }

  static transpose(matrix) {
    return new Matrix(matrix.cols, matrix.rows)
      .map((_, i, j) => matrix.data[j][i]);
  }

  static multiply(a, b) {
    // Matrix product
    if (a.cols !== b.rows) {
      console.log('Columns of A must match rows of B.')
      return;
    }

    return new Matrix(a.rows, b.cols)
      .map((e, i, j) => {
        // Dot product of values in col
        let sum = 0;
        for (let k = 0; k < a.cols; k++) {
          sum += a.data[i][k] * b.data[k][j];
        }
        return sum;
      });
  }

  multiply(n) {
    if (n instanceof Matrix) {
      if (this.rows !== n.rows || this.cols !== n.cols) {
        console.log('Columns and Rows of A must match Columns and Rows of B.');
        return;
      }

      // hadamard product
      return this.map((e, i, j) => e * n.data[i][j]);
    } else {
      // Scalar product
      return this.map(e => e * n);
    }
  }

  map(func) {
    // Apply a function to every element of matrix
    for (let i = 0; i < this.rows; i++) {
      for (let j = 0; j < this.cols; j++) {
        let val = this.data[i][j];
        this.data[i][j] = func(val, i, j);
      }
    }
    return this;
  }

  static map(matrix, func) {
    // Apply a function to every element of matrix
    return new Matrix(matrix.rows, matrix.cols)
      .map((e, i, j) => func(matrix.data[i][j], i, j));
  }

  print() {
    console.table(this.data);
    return this;
  }

  serialize() {
    return JSON.stringify(this);
  }

  static deserialize(data) {
    if (typeof data == 'string') {
      data = JSON.parse(data);
    }
    let matrix = new Matrix(data.rows, data.cols);
    matrix.data = data.data;
    return matrix;
  }
}

if (typeof module !== 'undefined') {
  module.exports = Matrix;
}

```

so in conclusion his code at this stage sends the bird up or down. mine gives me an error.

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [July 22, 2018, 6:34am UTC](https://discourse.processing.org/t/flappy-birds-notepad-javascript/1975/2 "2018-07-22T06:34:45Z")

</div>

What error do you get? If this is the same code as in his video, you could get the code from his github repo and compare it.

Kf

---

<div class="post-metadata">

**Author:** ![ctrembla](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@ctrembla](https://discourse.processing.org/u/ctrembla)\
**Post date:** [July 22, 2018, 3:53pm UTC](https://discourse.processing.org/t/flappy-birds-notepad-javascript/1975/3 "2018-07-22T15:53:11Z")

</div>

I was following along with him copying his code to see if I can get his nn to work and then maybe make it work on other games that I create. I followed the code to the letter. It says it can’t find neuralnetwork or it dont exist. Does the code work when you try it?
