AI Flappy Bird Processing Java

to change from 16 to 8 i wold just change the 2 16s in look right?

Yep, change that two 16s

1 Like

Is there a way to use the look function but make the line point frontwards instead at an angle, I guess frontwards is relative to the game lol, but when I look at the lines in my game all are hitting walls. I was wanting one to point the way the enemy should go. You can see my course in the picture I posted yesterday.

it would be easier if i could run your codes. are you using processing ide? or something else? i have the latest version of processing, and i still cannot run your codes

Processing 3.5.3. Are you sure you just can’t run it because you dont got the table? or did you comment that out?

lemme check the csv file

i’ll make it easy and place the walls in without it
here sketch without the tables

int s = 20;
int hw;
int Total = 500;
ArrayList<Enemy> population, saved;
ArrayList<Wall> wall = new ArrayList<Wall>();
int gen;
int mgen = 5;
int mmove = 5;
EndArea ea;
int bests[] = new int[5];
int beste[] = new int[5];
Table wallTable,genTable;
TableRow wallRow,genRow;
int map = 0;
int col;
float hisc,higen;
int ro;

void setup(){
  size(700,580);
  for (int i = 0; i < 5; i++){
    bests[i] = 0;
    beste[i] = 0;
  }
  genTable = loadTable("gen.csv");
  genRow = genTable.getRow(0);
  ro = genRow.getInt(0);
  ro += 1;
  genRow.setInt(0,ro);
  genRow = genTable.addRow();
  saveTable(genTable,"gen.csv");
  ea = new EndArea(26,25);
  loadSnake();
  population = new ArrayList<Enemy>();
  saved = new ArrayList<Enemy>();
  /*wallTable = loadTable("wall.csv");
  col = wallTable.getColumnCount();
  hw = height/s - 1;
  for (int i = 0; i <= col-1; i++){
    int tr = map*2;
    wallRow = wallTable.getRow(tr);
    int xx = wallRow.getInt(i);
    wallRow = wallTable.getRow(tr+1);
    int yy = wallRow.getInt(i);
    wall.add(new Wall(xx,yy));
  }*/
  for (int i = 0; i < Total; i++){
    population.add(new Enemy());
  }
  for (int i = 0; i < 29; i++){
    wall.add(new Wall(i,0));
    wall.add(new Wall(i,28));
    wall.add(new Wall(0,i));
    wall.add(new Wall(28,i));
  }
  for (int i = 0; i < 23; i++){
    wall.add(new Wall(i,4));
    wall.add(new Wall(6 + i,8));
    wall.add(new Wall(i,12));
    wall.add(new Wall(6 + i,16));
    wall.add(new Wall(i,20));
    wall.add(new Wall(6 + i,24));
  }
}

void draw(){
  background(0);
  fill(255);
  textSize(20);
  text("Gen: " + gen, 29 * s, 1 * s);
  text("HS: " + int(hisc), 29 * s, 2 * s);
  text("HG: " + int(higen), 29 * s, 3 * s);
  text("Pop: " + population.size(), 29 * s, 4 * s);
  if (population.size() == 0){
    nextGeneration();
  }
  for (Enemy e: population){
    e.check();
    e.look();
    e.think();
  }
  for (int i = population.size()-1; i >= 0; i--){
    Enemy e = population.get(i);
    if (e.collide == true || e.won == true || e.failed == true){
      saved.add(e);
      population.remove(i);
    }
  }
  
  for (Wall w: wall){
    w.show();
  }
  ea.show();
  for (Enemy e: population){
    e.show();
  }
}

here EndArea

class EndArea{
  int x,y;
  int h = s*3;
  int w = s * 2;
  EndArea(int x, int y){
    this.x = x*s;
    this.y = y*s;
  }
  
  void show(){
    fill(0,255,0);
    rect(x,y,w,h);
  }
}

here Enemy

class Enemy{
  PVector pos;
  int r = 12;
  float score = 0;
  float fitness = 0;
  float nx,ny;
  boolean collide = false;
  boolean won = false;
  boolean failed;
  int timer = 100;
  int nummove = 0;
  float sy,cd,sd;
  
  float[] inputs = new float[12];
  NeuralNetwork brain;
  
  Enemy(){
    pos = new PVector(2 * s, 2 * s);
    sy = pos.y;
    sd = dist(ea.x,ea.y,pos.x,pos.y);
    nx = pos.x;
    ny = pos.y;
    brain = new NeuralNetwork(12, 94, 4);
  }
  Enemy(NeuralNetwork b){
    pos = new PVector(2 * s, 2 * s);
    sy = pos.y;
    sd = dist(ea.x,ea.y,pos.x,pos.y);
    nx = pos.x;
    ny = pos.y;
    brain = b.clone();
  }
  
  void mutate(){
    brain.mutate(0.1);
  }
  
  void think(){
    inputs[8] = pos.x;
    inputs[9] = pos.y;
    inputs[10] = ea.x;
    inputs[11] = ea.y;
    float[] guess = brain.output(inputs);
    if (guess[0] > guess[1] && guess[0] > guess[2] && guess[0] > guess[3]){move(0,-1);}
    if (guess[1] > guess[0] && guess[1] > guess[2] && guess[1] > guess[3]){move(0,1);}
    if (guess[2] > guess[1] && guess[2] > guess[0] && guess[2] > guess[3]){move(-1,0);}
    if (guess[3] > guess[0] && guess[3] > guess[2] && guess[3] > guess[0]){move(1,0);}
  }
  
  void show(){
    if (timer > -1){timer -= 1;}
    if (timer <= 0 && won == false){
      float d = dist(nx,ny,pos.x,pos.y);
      if (d < s){
        failed = true;
      }
      else {
        nx = pos.x;
        ny = pos.y;
        timer = 40;
        cd = dist(ea.x,ea.y,pos.x,pos.y);
        if (cd < sd){
          sd = cd;
          score += 1;
        }
      }
    }
    if (pos.y > sy + (s*2)){score += 1;}
    fill(255,0,0);
    stroke(0);
    rect(pos.x,pos.y,s,s);
  }
  
  void check(){
    for (int i = 0; i < wall.size(); i++){
      Wall w = wall.get(i);
      float d = dist(w.pos.x,w.pos.y,pos.x,pos.y);
      if (d < s){
        collide = true;
      }
    }// wall
    if (pos.x >= ea.x && pos.x < ea.x + ea.w && pos.y >= ea.y && pos.y < ea.y + ea.h){
      won = true;
      score = score * 2;
    }
  }// check
  
  void move(int xspd, int yspd){
    if (won == false){
      pos.x += xspd;
      pos.y += yspd;
    }
    xspd = 0;
    yspd = 0;
  }
  void look() {
    PVector direction;
    for (int i = 0; i< 8; i++) {
      // player sees in 16 direction, so we have to divide one full rotation (360 degrees) with 16
      // so angle between two nearest directions will be 22.5 degree
      direction = PVector.fromAngle(i*(TWO_PI/8));
      direction.mult(10);
      // get the normalized distance to the ball if found in the current direction
      // if got no ball in the current direction, mag will be zero
      float mag = lookInDirection(direction); 
      inputs[i] = mag; //feed this to the input
      
      // this is how the visualisation
      stroke(255,0,0);
      if (mag > 0) {
        direction.mult(1/mag);
        direction.add(pos);
        fill(0);
        //text(1/mag, direction.x, direction.y);
        stroke(0, 255,0);
      }else{
        //if no ball in current direction
        direction.mult(60);
        direction.add(pos);
        stroke(255, 0,0);
      }
      line(pos.x, pos.y, direction.x, direction.y);
    }
  }

  float lookInDirection(PVector direction) {

    PVector position = new PVector(pos.x, pos.y);//the position where we are currently looking for the balls
    float distance = 0;
    //move once in the desired direction before starting 
    position.add(direction);
    distance +=1;

    //look in the direction
    while (distance< 60) {
      for (Wall a: wall) {
        if (a.lookForHit(position) ) { 
          // found ball
          return  1/distance;
        }
      }

      //look further in the direction
      position.add(direction);

      // next distance
      distance +=1;
    }
    return 0;
  }
  
  void saveEnemy() {
    //save snakes brain
    saveTable(brain.NetToTable(), "data/Snake.csv");
  }
}

here GA

void nextGeneration(){
  getBest();
  for (int i = 0; i < Total-5; i++){
    population.add(pickOne());
  }
  for (int i = 0; i < 5; i++){
    population.add(new Enemy());
  }
  population.add(bestOne());
  gen++;
  if (gen == 100){
    exit();
  }
}

Enemy bestOne(){
  int index = 0;
  index = beste[0];
  Enemy b = saved.get(index);
  Enemy child = new Enemy(b.brain);
  return child;
}

Enemy pickOne(){// pick an enemy from the top 5
  int index = 0;
  float choose = random(4);
  choose = round(choose);
  index = beste[int(choose)];
  Enemy b = saved.get(index);
  Enemy child = new Enemy(b.brain);
  child.mutate();
  return child;
}

Enemy loadSnake() {

    Enemy load = new Enemy();
    Table t = loadTable("data/Snake.csv");
    load.brain.TableToNet(t);
    return load;
  }

void getBest(){// loop through all the enemies and get the scores
  for (int i = 0; i < saved.size(); i++){
    Enemy s = saved.get(i);
    if (s.score > bests[0]){
      bests[4] = bests[3];
      bests[3] = bests[2];
      bests[2] = bests[1];
      bests[1] = bests[0];
      bests[0] = int(s.score);
      beste[4] = beste[3];
      beste[3] = beste[2];
      beste[2] = beste[1];
      beste[1] = beste[0];
      beste[0] = i;
      if (s.score > hisc){
        hisc = s.score;
        higen = gen;
        s.saveEnemy();
      }
    }
    else if (s.score > bests[1]){
      bests[4] = bests[3];
      bests[3] = bests[2];
      bests[2] = bests[1];
      bests[1] = int(s.score);
      beste[4] = beste[3];
      beste[3] = beste[2];
      beste[2] = beste[1];
      beste[1] = i;
    }
    else if (s.score > bests[2]){
      bests[4] = bests[3];
      bests[3] = bests[2];
      bests[2] = int(s.score);
      beste[4] = beste[3];
      beste[3] = beste[2];
      beste[2] = i;
    }
    else if (s.score > bests[3]){
      bests[4] = bests[3];
      bests[3] = int(s.score);
      beste[4] = beste[3];
      beste[3] = i;
    }
    else if (s.score > bests[4]){
      bests[4] = int(s.score);
      beste[4] = i;
    }
  }
}

here Matrix, i changed it

class Matrix {
  
  //local variables
  int rows;
  int cols;
  float[][] matrix;
  
  //---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //constructor
  Matrix(int r, int c) {
    rows = r;
    cols = c;
    matrix = new float[rows][cols];
  }
  
  //---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //constructor from 2D array
  Matrix(float[][] m) {
    matrix = m;
    cols = m.length;
    rows = m[0].length;
  }
  
  //---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //print matrix
  void output() {
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        print(matrix[i][j] + "  ");
      }
      println(" ");
    }
    println();
  }
  //---------------------------------------------------------------------------------------------------------------------------------------------------------  
  
  //multiply by scalar
  void multiply(float n ) {

    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        matrix[i][j] *= n;
      }
    }
  }

//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //return a matrix which is this matrix dot product parameter matrix 
  Matrix dot(Matrix n) {
    Matrix result = new Matrix(rows, n.cols);
   
    if (cols == n.rows) {
      //for each spot in the new matrix
      for (int i =0; i<rows; i++) {
        for (int j = 0; j<n.cols; j++) {
          float sum = 0;
          for (int k = 0; k<cols; k++) {
            sum+= matrix[i][k]*n.matrix[k][j];
          }
          result.matrix[i][j] = sum;
        }
      }
    }

    return result;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //set the matrix to random ints between -1 and 1
  void randomize() {
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        matrix[i][j] = random(-1, 1);
      }
    }
  }

//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //add a scalar to the matrix
  void Add(float n ) {
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        matrix[i][j] += n;
      }
    }
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  ///return a matrix which is this matrix + parameter matrix
  Matrix add(Matrix n ) {
    Matrix newMatrix = new Matrix(rows, cols);
    if (cols == n.cols && rows == n.rows) {
      for (int i =0; i<rows; i++) {
        for (int j = 0; j<cols; j++) {
          newMatrix.matrix[i][j] = matrix[i][j] + n.matrix[i][j];
        }
      }
    }
    return newMatrix;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //return a matrix which is this matrix - parameter matrix
  Matrix subtract(Matrix n ) {
    Matrix newMatrix = new Matrix(cols, rows);
    if (cols == n.cols && rows == n.rows) {
      for (int i =0; i<rows; i++) {
        for (int j = 0; j<cols; j++) {
          newMatrix.matrix[i][j] = matrix[i][j] - n.matrix[i][j];
        }
      }
    }
    return newMatrix;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //return a matrix which is this matrix * parameter matrix (element wise multiplication)
  Matrix multiply(Matrix n ) {
    Matrix newMatrix = new Matrix(rows, cols);
    if (cols == n.cols && rows == n.rows) {
      for (int i =0; i<rows; i++) {
        for (int j = 0; j<cols; j++) {
          newMatrix.matrix[i][j] = matrix[i][j] * n.matrix[i][j];
        }
      }
    }
    return newMatrix;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //return a matrix which is the transpose of this matrix
  Matrix transpose() {
    Matrix n = new Matrix(cols, rows);
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        n.matrix[j][i] = matrix[i][j];
      }
    }
    return n;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //Creates a single column array from the parameter array
  Matrix singleColumnMatrixFromArray(float[] arr) {
    Matrix n = new Matrix(arr.length, 1);
    for (int i = 0; i< arr.length; i++) {
      n.matrix[i][0] = arr[i];
    }
    return n;
  }
  //---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //sets this matrix from an array
  void fromArray(float[] arr) {
    for (int i = 0; i< rows; i++) {
      for (int j = 0; j< cols; j++) {
        matrix[i][j] =  arr[j+i*cols];
      }
    }
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------    
  //returns an array which represents this matrix
  float[] toArray() {
    float[] arr = new float[rows*cols];
    for (int i = 0; i< rows; i++) {
      for (int j = 0; j< cols; j++) {
        arr[j+i*cols] = matrix[i][j];
      }
    }
    return arr;
  }

//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //for ix1 matrixes adds one to the bottom
  Matrix addBias() {
    Matrix n = new Matrix(rows+1, 1);
    for (int i =0; i<rows; i++) {
      n.matrix[i][0] = matrix[i][0];
    }
    n.matrix[rows][0] = 1;
    return n;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //applies the activation function(sigmoid) to each element of the matrix
  Matrix activate() {
    Matrix n = new Matrix(rows, cols);
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        n.matrix[i][j] = sigmoid(matrix[i][j]);
      }
    }
    return n;
  }
  
//---------------------------------------------------------------------------------------------------------------------------------------------------------    
  //sigmoid activation function
  float sigmoid(float x) {
    float y = 1 / (1 + pow((float)Math.E, -x));
    return y;
  }
  //returns the matrix that is the derived sigmoid function of the current matrix
  Matrix sigmoidDerived() {
    Matrix n = new Matrix(rows, cols);
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        n.matrix[i][j] = (matrix[i][j] * (1- matrix[i][j]));
      }
    }
    return n;
  }

//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //returns the matrix which is this matrix with the bottom layer removed
  Matrix removeBottomLayer() {
    Matrix n = new Matrix(rows-1, cols);      
    for (int i =0; i<n.rows; i++) {
      for (int j = 0; j<cols; j++) {
        n.matrix[i][j] = matrix[i][j];
      }
    }
    return n;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //Mutation function for genetic algorithm 
  
  void mutate(float mutationRate) {
    
    //for each element in the matrix
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        float rand = random(1);
        if (rand<mutationRate) {//if chosen to be mutated
          matrix[i][j] += randomGaussian()/5;//add a random value to it(can be negative)
          
          //set the boundaries to 1 and -1
          if (matrix[i][j]>1) {
            matrix[i][j] = 1;
          }
          if (matrix[i][j] <-1) {
            matrix[i][j] = -1;
          }
        }
      }
    }
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //returns a matrix which has a random number of values from this matrix and the rest from the parameter matrix
  Matrix crossover(Matrix partner) {
    Matrix child = new Matrix(rows, cols);
    
    //pick a random point in the matrix
    int randC = floor(random(cols));
    int randR = floor(random(rows));
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {

        if ((i< randR)|| (i==randR && j<=randC)) { //if before the random point then copy from this matric
          child.matrix[i][j] = matrix[i][j];
        } else { //if after the random point then copy from the parameter array
          child.matrix[i][j] = partner.matrix[i][j];
        }
      }
    }
    return child;
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------  
  //return a copy of this matrix
  Matrix clone() {
    Matrix clone = new  Matrix(rows, cols);
    for (int i =0; i<rows; i++) {
      for (int j = 0; j<cols; j++) {
        clone.matrix[i][j] = matrix[i][j];
      }
    }
    return clone;
  }
}

here NN, also been changed

class NeuralNetwork{
  int iNodes;
  int hNodes;
  int oNodes;
  
  Matrix whi,whh,woh;
  
  NeuralNetwork(int inputs, int hiddenNo, int outputNo){
    iNodes = inputs;
    oNodes = outputNo;
    hNodes = hiddenNo;
    whi = new Matrix(hNodes, iNodes +1);
    whh = new Matrix(hNodes, hNodes +1);
    woh = new Matrix(oNodes, hNodes +1);
    whi.randomize();
    whh.randomize();
    woh.randomize();
  }
  
  float mut(float val, float rate){
    if (random(1) > rate){
      return val + randomGaussian() * .1;
    } else{
      return val;
    }
  }
  
  NeuralNetwork clone() {
    NeuralNetwork clone  = new NeuralNetwork(iNodes, hNodes, oNodes); 
    clone.whi = whi.clone();
    clone.whh = whh.clone();
    clone.woh = woh.clone();

    return clone;
  }
  
  void mutate(float mr) {
    //mutates each weight matrix
    whi.mutate(mr);
    whh.mutate(mr);
    woh.mutate(mr);
  }
  
  float[] output(float[] inputsArr) {

    //convert array to matrix
    //Note woh has nothing to do with it its just a function in the Matrix class
    Matrix inputs = woh.singleColumnMatrixFromArray(inputsArr);

    //add bias 
    Matrix inputsBias = inputs.addBias();

    //apply layer one weights to the inputs
    Matrix hiddenInputs = whi.dot(inputsBias);

    //pass through activation function(sigmoid)
    Matrix hiddenOutputs = hiddenInputs.activate();

    //add bias
    Matrix hiddenOutputsBias = hiddenOutputs.addBias();

    //apply layer two weights
    Matrix hiddenInputs2 = whh.dot(hiddenOutputsBias);
    Matrix hiddenOutputs2 = hiddenInputs2.activate();
    Matrix hiddenOutputsBias2 = hiddenOutputs2.addBias();

    //apply level three weights
    Matrix outputInputs = woh.dot(hiddenOutputsBias2);
    //pass through activation function(sigmoid)
    Matrix outputs = outputInputs.activate();

    //convert to an array and return
    return outputs.toArray();
  }////////////////////////////////////////////////////////////////////////////
  
  NeuralNetwork crossover(NeuralNetwork partner) {

    //creates a new child with layer matrices from both parents
    NeuralNetwork child = new NeuralNetwork(iNodes, hNodes, oNodes);
    child.whi = whi.crossover(partner.whi);
    child.whh = whh.crossover(partner.whh);
    child.woh = woh.crossover(partner.woh);
    return child;
  }
  
   Table NetToTable() {

    //create table
    Table t = new Table();


    //convert the matricies to an array 
    float[] whiArr = whi.toArray();
    float[] whhArr = whh.toArray();
    float[] wohArr = woh.toArray();

    //set the amount of columns in the table
    for (int i = 0; i< max(whiArr.length, whhArr.length, wohArr.length); i++) {
      t.addColumn();
    }

    //set the first row as whi
    TableRow tr = t.addRow();

    for (int i = 0; i< whiArr.length; i++) {
      tr.setFloat(i, whiArr[i]);
    }


    //set the second row as whh
    tr = t.addRow();

    for (int i = 0; i< whhArr.length; i++) {
      tr.setFloat(i, whhArr[i]);
    }

    //set the third row as woh
    tr = t.addRow();

    for (int i = 0; i< wohArr.length; i++) {
      tr.setFloat(i, wohArr[i]);
    }

    //return table
    return t;
  }
  
  void TableToNet(Table t) {

    //create arrays to tempurarily store the data for each matrix
    float[] whiArr = new float[whi.rows * whi.cols];
    float[] whhArr = new float[whh.rows * whh.cols];
    float[] wohArr = new float[woh.rows * woh.cols];

    //set the whi array as the first row of the table
    TableRow tr = t.getRow(0);

    for (int i = 0; i< whiArr.length; i++) {
      whiArr[i] = tr.getFloat(i);
    }


    //set the whh array as the second row of the table
    tr = t.getRow(1);

    for (int i = 0; i< whhArr.length; i++) {
      whhArr[i] = tr.getFloat(i);
    }

    //set the woh array as the third row of the table

    tr = t.getRow(2);

    for (int i = 0; i< wohArr.length; i++) {
      wohArr[i] = tr.getFloat(i);
    }


    //convert the arrays to matrices and set them as the layer matrices 
    whi.fromArray(whiArr);
    whh.fromArray(whhArr);
    woh.fromArray(wohArr);
  }
 }

here wall

class Wall{
  PVector pos;
  Wall(int x, int y){
    pos = new PVector(x*s,y*s);
  }
  
  void show(){
    fill(150,75,0);
    stroke(0);
    rect(pos.x,pos.y,s,s);
  }
  
   boolean lookForHit(PVector loc) {
   // circle collision detection
    if (dist(pos.x, pos.y, loc.x, loc.y)< 50) {
      return true;
    }
    return false;
  }
}

you should be able to run this

im stuck at those static methods you have written before in matrix class. and got some other errors due to that in nn too. now i can run the codes you just posted with some other csvs commented out

add this import java.io.File; to top it might be needed

1 Like

Did you get it to work?

i found some problems.
in wall class, you cannot use circle collision detection. you have to use collision detection for rectangle since it is a block

boolean lookForHit(PVector loc) { 
 // circle collision detection
    //if (dist(pos.x, pos.y, loc.x, loc.y)< 50) {

   //rectangle collision detection
    if(loc.x > pos.x && loc.x < pos.x + s && loc.y > pos.y && loc.y  < pos.y + s){
      return true;
    }
    return false;
  }

like youve been using in check() function
if (pos.x >= ea.x && pos.x < ea.x + ea.w && pos.y >= ea.y && pos.y < ea.y + ea.h){

then the problem with normalization

    inputs[8] = pos.x;
    inputs[9] = pos.y;
    inputs[10] = ea.x;
    inputs[11] = ea.y;

dont forget to normalize the value first when it comes to be fired through the NN

 inputs[10] = ea.x;
     inputs[11] = ea.y;

just input the distance to the endarea. its better than its position.

and for this

    inputs[8] = pos.x;
    inputs[9] = pos.y;

you can just ignore its current position, since the player got enough information.

btw, the program will run smoothier if there are no strokes to be dislpayed. stroke() function is bad in performance

you can just increase how many directions the player sees, otherwise, you can manipulate the starting angle while scanning its environment

in the look() function, you can change the high of accuracy it get while scanning by decrease the direction magnitude direction.mult(10);
just change it to like direction.mult(5);

1 Like

so make the dist input 8? and fix the wall anything else?

1/dist(); anyway

little hack,
distance calculation between two point with dist() function is bad too. you can replace it with this

float dx = pos.x - target.x;
float dy = pos.y - target.y;
float d = sqrt(sq(dx) + sq(dy)); //simple euclidean distance formula

it do the same, but faster

Nice, cool. Do I normalize it the same way?

right

//ignore this. just make sure the character more than 20

1 Like