Hi I’m trying to learn to build an AI from the flappy bird video from coding train. I got another game I’m using what I learn on, anyways I reached the part of the video where he saves the bird in js & tried several ways to copy it in java but failed. He turns the bird in a string then saves it then loads it. Very useful when making an AI.
here sketch
ArrayList<bird> population, saved;
ArrayList<pipe> pipes;
float TOTAL;
int Gens;
float counter;
int con = 0;
void setup()
{
size(640, 480);
TOTAL = 550;
pipes = new ArrayList<pipe>();
population = new ArrayList<bird>();
saved = new ArrayList<bird>();
for (int i = 0; i < TOTAL; i++)
{
population.add(new bird());
}
counter = 0;
}
void draw()
{
background(51);
fill(255);
textSize(30);
text("Bird: " + population.size(), 10, 30);
text("Count: " + con, 10, 60);
text("Gen: " + Gens, 10, 90);
if (counter % 75 == 0)
{
pipes.add(new pipe());
con += 1;
}
for (int i = pipes.size()-1; i >= 0; i--)
{
pipe p = pipes.get(i);
p.update();
if (p.offscreen())
{
pipes.remove(i);
}
for (int j = population.size()-1; j >= 0; j--)
{
bird b = population.get(j);
if (p.hit(b) || b.dead())
{
saved.add(b);
population.remove(j);
}
}
}
if (population.size() == 0)
{
counter = 0;
nextGeneration();
pipes.clear();
pipes.add(new pipe());
}
for (bird b : population)
{
b.show();
b.update();
b.think(pipes);
}
for (int i = pipes.size()-1; i >= 0; i--)
{
pipe p = pipes.get(i);
p.show();
}
counter++;
}
void keyPressed(){// here the problem
if (key == 's'){
float sbird = population.get(0);
String json = sbird.serialize();
}
}
here ga
void nextGeneration(){
Gens++;
println("Generation "+ Gens);
calculateFitness();
for (int i = 0; i < TOTAL; i++){
population.add(pickOne());
}
saved.clear();
}
bird pickOne(){
con = 0;
int index = 0;
float r = random(1);
while (r > 0) {
r -= saved.get(index).fitness;
index++;
}
index--;
bird b = saved.get(index);
bird child = new bird(b.brain);
child.mutate();
return child;
}
void calculateFitness(){
float sum = 0;
for (bird b : saved){
sum += b.score;
}
for (bird b : saved){
b.fitness = b.score/sum;
}
}
here matrix.java
class Matrix{
int rows, cols;
float[][] values;
Matrix(int rows, int cols){
this.rows = rows;
this.cols = cols;
values = new float[this.rows][this.cols];
}
Matrix(){
rows = 1;
cols = 1;
values = new float[rows][cols];
}
Matrix copy(){
Matrix result = new Matrix(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result.values[i][j] = values[i][j];
}
}
return result;
}
static String[][] stringify(Matrix a){
String[][] result = new String[a.rows][a.cols];
for (int i = 0; i < a.rows; i++){
for (int j = 0; j < a.cols; j++){
result[i][j] = i+" " + j+" " + a.values[i][j]+" ";
}
}
return result;
}
void multiply(float n){
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
values[i][j] *= n;
}
}
}
void add(float n){
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
values[i][j] += n;
}
}
}
static Matrix random(int rows, int cols){
Matrix result = new Matrix(rows, cols);
result.randomize();
return result;
}
void randomize(){
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
values[i][j] = (float) Math.random() * 2 - 1;
}
}
}
static Matrix subtract(Matrix a, Matrix b){
Matrix result = new Matrix(a.rows, a.cols);
for (int i = 0; i < a.rows; i++){
for (int j = 0; j < a.cols; j++){
result.values[i][j] = a.values[i][j] - b.values[i][j];
}
}
return result;
}
static Matrix FromArray(float[] arr){
Matrix result = new Matrix(arr.length, 1);
for (int i = 0; i < result.rows; i++){
result.values[i][0] = arr[i];
}
return result;
}
float[] toArray(){
float[] arr = new float[rows+cols];
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
arr[i] = values[i][j];
}
}
return arr;
}
void add(Matrix other){
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
values[i][j] += other.values[i][j];
}
}
}
void multiply(Matrix other){
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
values[i][j] *= other.values[i][j];
}
}
}
static Matrix transpose(Matrix a){
Matrix result = new Matrix(a.cols, a.rows);
for (int i = 0; i < a.rows; i++){
for (int j = 0; j < a.cols; j++){
result.values[j][i] = a.values[i][j];
}
}
return result;
}
static Matrix Product(Matrix first, Matrix second){
if (first.cols != second.rows){
return null;
} else{
Matrix a = first;
Matrix b = second;
Matrix result = new Matrix(a.rows, b.cols);
for (int i = 0; i < result.rows; i++){
for (int j = 0; j < result.cols; j++){
float sum = 0;
for (int k = 0; k < a.cols; k++){
sum += a.values[i][k] * b.values[k][j];
}
result.values[i][j] = sum;
}
}
return result;
}
}
}
here neural network
float sigmoid(float x){
return 1 / (1+(float)Math.exp(-x));
}
float dsigmoid(float y){
return y * (1-y);
}
float tanh(float x){
float y = (float) Math.tanh(x);
return y;
}
float dtanh(float x) {
float y = 1 / (pow((float) Math.cosh(x), 2));
return y;
}
class NeuralNetwork{
int
inputNodes,
hiddenNodes,
outputNodes;
float LearningRate = .1;
Matrix
IHWeights,
HOWeights,
Hbias,
Obias,
input,
hidden,
output;
NeuralNetwork(NeuralNetwork copy){
inputNodes = copy.inputNodes;
hiddenNodes = copy.hiddenNodes;
outputNodes = copy.outputNodes;
IHWeights = copy.IHWeights.copy();
HOWeights = copy.HOWeights.copy();
Hbias = copy.Hbias.copy();
Obias = copy.Obias.copy();
}
NeuralNetwork(int input, int hidden, int output){
inputNodes = input;
hiddenNodes = hidden;
outputNodes = output;
IHWeights = Matrix.random(hiddenNodes, inputNodes);
HOWeights = Matrix.random(outputNodes, hiddenNodes);
Hbias = Matrix.random(hiddenNodes, 1);
Obias = Matrix.random(outputNodes, 1);
}
NeuralNetwork(int input, int hidden, int output, float lr){
this(input, hidden, output);
setLearingRate(lr);
}
NeuralNetwork copy(){
return new NeuralNetwork(this);
}
float mut(float val, float rate){
if (random(1) > rate){
return val + randomGaussian() * .1;
} else{
return val;
}
}
void mutate(float rate){
for (int i = 0; i < IHWeights.rows; i++){
for (int j = 0; j < IHWeights.cols; j++){
float val = IHWeights.values[i][j];
IHWeights.values[i][j] = mut(val, rate);
}
}
for (int i = 0; i < HOWeights.rows; i++){
for (int j = 0; j < HOWeights.cols; j++){
float val = HOWeights.values[i][j];
HOWeights.values[i][j] = mut(val, rate);
}
}
for (int i = 0; i < Hbias.rows; i++){
for (int j = 0; j < Hbias.cols; j++){
float val = Hbias.values[i][j];
Hbias.values[i][j] = mut(val, rate);
}
}
for (int i = 0; i < Obias.rows; i++){
for (int j = 0; j < Obias.cols; j++){
float val = Obias.values[i][j];
Obias.values[i][j] = mut(val, rate);
}
}
}
void setLearingRate(float rate){
LearningRate = rate;
}
float[] feedForward(float[] inputArray){
input = Matrix.FromArray(inputArray);
//generating hidden inputs
hidden = Matrix.Product(IHWeights, input);
hidden.add(Hbias);
//activation function for hidden nodes!
for (int i = 0; i < hidden.rows; i++){
for (int j = 0; j < hidden.cols; j++){
float val = hidden.values[i][j];
hidden.values[i][j] = sigmoid(val);
}
}
//generating hidden output
output = Matrix.Product(HOWeights, hidden);
output.add(Obias);
//activation function for ouput nodes!
for (int i = 0; i < output.rows; i++){
for (int j = 0; j < output.cols; j++){
float val = output.values[i][j];
output.values[i][j] = sigmoid(val);
}
}
//generating the output array
return output.toArray();
}
void train(float[] inputArray, float[] targetArray){
feedForward(inputArray);
Matrix targets = Matrix.FromArray(targetArray);
Matrix outputErrors = Matrix.subtract(targets, output);
//java version of matrix map function
Matrix gradient = output.copy();
for (int i = 0; i < gradient.rows; i++){
for (int j = 0; j < gradient.cols; j++){
float val = gradient.values[i][j];
gradient.values[i][j] = dsigmoid(val);
}
}
gradient.multiply(outputErrors); //elementWise
gradient.multiply(LearningRate); //Scalar
Matrix hiddenT = Matrix.transpose(hidden);
Matrix DHOWeights = Matrix.Product(gradient, hiddenT);
HOWeights.add(DHOWeights);
Obias.add(gradient);
Matrix HOWeightsT = Matrix.transpose(HOWeights);
Matrix hiddenErrors = Matrix.Product(HOWeightsT, outputErrors);
//java version of matrix map function
Matrix hiddenGradient = hidden.copy();
for (int i = 0; i < hiddenGradient.rows; i++){
for (int j = 0; j < hiddenGradient.cols; j++){
float val = hiddenGradient.values[i][j];
hiddenGradient.values[i][j] = dsigmoid(val);
}
}
hiddenGradient.multiply(hiddenErrors);
hiddenGradient.multiply(LearningRate);
Matrix inputT = Matrix.transpose(input);
Matrix DIHWeights = Matrix.Product(hiddenGradient, inputT);
IHWeights.add(DIHWeights);
Hbias.add(hiddenGradient);
}
}
here pipe
class pipe{
float top;
float bottom;
float x;
float w;
float speed;
float spacing;
pipe(){
spacing = 125;
top = random(height/ 6, .75 * height);
bottom = height - (top + spacing);
w = 80;
x = width;
speed = 6;
}
void show(){
fill(255);
rectMode(CORNER);
rect(x, 0, w, top);
rect(x, height-bottom, w, bottom);
}
void update(){
x -= speed;
}
boolean offscreen(){
return x < -w;
}
boolean hit(bird b){
if (b.pos.y < top+b.r || b.pos.y+b.r > height-bottom){
if (b.pos.x+b.r > x && b.pos.x < (x + w)+b.r)
return true;
}
return false;
}
}
here bird
class bird{
PVector pos, vel, acc;
PVector gravity, jump;
float r = 16;
float d = r * 2;
boolean alive = true;
float[] inputs = new float[5];
float score = 0;
float fitness = 0;
NeuralNetwork brain;
bird(){
pos = new PVector(64, height/2);
vel = new PVector();
gravity = new PVector(0, .8);
jump = new PVector(0, 16);
score = 0;
fitness = 0;
brain = new NeuralNetwork(5, 64, 2);
}
bird(NeuralNetwork b){
pos = new PVector(64, height/2);
vel = new PVector();
gravity = new PVector(0, .8);
jump = new PVector(0, -12);
score = 0;
fitness = 0;
brain = b.copy();
}
void mutate(){
brain.mutate(.01);
}
void think(ArrayList<pipe> pipe){
pipe closest = null;
float recordD = Float.POSITIVE_INFINITY;
for (int i = 0; i < pipe.size(); i++){
pipe p = pipe.get(i);
float d = (p.x+p.w) - pos.x;
if (d < recordD && d > 0){
closest = pipe.get(i);
recordD = d;
}
}
inputs[0] = pos.y / height;
inputs[1] = vel.y / 10;
inputs[2] = closest.top / height;
inputs[3] = closest.bottom / width;
inputs[4] = closest.x / width;
float[] guess = brain.feedForward(inputs);
if (guess[0] > guess[1]){
jump();
}
}
void show(){
stroke(255);
fill(255, 100);
circle(pos.x, pos.y, d);
}
void update(){
score++;
vel.add(gravity);
pos.add(vel);
}
void jump(){
vel.add(jump);
}
boolean dead(){
return (pos.y+r > height || pos.y < r);
}
}
so can anyone help me save the bird to a file?