OK, so here the code for my machine learning. It works good but can be dumb. But it did make it to the end. It has room cause I was gonna throw a menu and high score and ect in it
mazeRunner
int s = 25;
ArrayList<Wall> wall = new ArrayList<Wall>();
ArrayList<Enemy> enemy = new ArrayList<Enemy>();
ArrayList<Enemy> saved = new ArrayList<Enemy>();
ArrayList<endPoint> end = new ArrayList<endPoint>();
boolean created = false;
Table wallTable;
TableRow tr;
int room = 1;
int total = 500;
int[] bs = new int[5];
int[] be = new int[5];
int gen = 0;
int hs = 0;
void setup(){
size(625,625);
wallTable = loadTable("wall.csv");
tr = wallTable.getRow(0);
int tn = tr.getInt(0);
for (int i = 0; i < tn; i++){
int tc = tr.getInt(i + 1);
wall.add(new Wall(tc));
}
end.add(new endPoint(552));
saved.add(loadSnake());
}
Enemy loadSnake() {
Enemy load = new Enemy(52);
Table t = loadTable("data/Snake.csv");
load.brain.TableToNet(t);
return load;
}
void draw(){
background(0);
if (room == 1){
for (int i = wall.size()-1; i >= 0; i--){
Wall w = wall.get(i);
w.show();
w.mouseCheck();
}
if (enemy.size() > 0){
Enemy e = enemy.get(0);
fill(255,0,0);
textSize(20);
text("gen: " + gen, 50, 150);
}
for (int i = enemy.size()-1; i >= 0; i--){
Enemy e = enemy.get(i);
e.show();
e.checkD();
e.checkW();
if (e.alive == false){
enemy.remove(i);
saved.add(e);
}
if (e.destroy == true){
enemy.remove(i);
}
}
for (int i = end.size()-1; i >= 0; i--){
endPoint e = end.get(i);
e.show();
}
if (enemy.size() == 0){
nextGen();
}
}
if (created){
tr = wallTable.addRow();
tr.setInt(0,wall.size()+1);
for (int i = 0; i < wall.size(); i++){
Wall w = wall.get(i);
tr.setInt(i+1,w.num);
}
saveTable(wallTable,"wall.csv");
exit();
}// created
}// draw
Enemy
class Enemy extends Rect{
int rd, ld, ud, dd;
float[] input = new float[5];
NeuralNet brain;
boolean alive = true;
boolean destroy = false;
PVector opos;
int timeBetween = 128;
int timer = timeBetween;
float d;
int score = 0;
int rc, lc, uc, dc;
Enemy(int n){
super(n);
opos = new PVector(pos.x,pos.y);
brain = new NeuralNet(input.length,8,4);
}
Enemy(int n, NeuralNet b){
super(n);
opos = new PVector(pos.x,pos.y);
brain = b.clone();
brain.mutate(0.1);
}
void saveSnake() {
//save snakes brain
saveTable(brain.NetToTable(), "data/Snake.csv");
}
void think(){
input[0] = rd;
input[1] = ld;
input[2] = ud;
input[3] = dd;
endPoint e = end.get(0);
input[4] = e.num;
float[] guess = brain.output(input);
if (guess[0] > guess[1] && guess[0] > guess[2] && guess[0] > guess[3]){
pos.x += s;
rc = 0;
lc = 2;
uc = 0;
dc = 0;
}
if (guess[1] > guess[0] && guess[1] > guess[2] && guess[1] > guess[3]){
pos.x -= s;
rc = 2;
lc = 0;
uc = 0;
dc = 0;
}
if (guess[2] > guess[1] && guess[2] > guess[0] && guess[2] > guess[3] && dc != 2){
pos.y += s;
rc = 0;
lc = 0;
uc = 2;
dc = 0;
}
if (guess[3] > guess[1] && guess[3] > guess[2] && guess[3] > guess[0] && uc != 2){
pos.y -= s;
rc = 0;
lc = 0;
uc = 0;
dc = 2;
}
checkW();
}
void checkW(){
for (int i = wall.size()-1; i >= 0; i--){
Wall w = wall.get(i);
if (pos.x == w.pos.x && pos.y == w.pos.y){
alive = false;
}
}
if (timer > -1){timer -= 1;}
if (timer < 0){
d = dist(pos.x,pos.y,opos.x,opos.y);
if (d < 64){
destroy = true;
}
timer = timeBetween;
opos = new PVector(pos.x,pos.y);
}
score += 1;
}
void checkD(){
rd = width;
ld = width;
ud = height;
dd = height;
for (int i = 0; i < wall.size(); i++){
Wall w = wall.get(i);
if (w.pos.y <= pos.y && w.pos.y + s >= pos.y){
d = int(w.pos.x - pos.x);
if (d > 0 && d < rd){
rd = int(d-25);
}
d = int(pos.x - w.pos.x);
if (d > 0 && d < ld){
ld = int(d-25);
}
}// y
if (w.pos.x <= pos.x && w.pos.x + s >= pos.x){
d = int(w.pos.y - pos.y);
if (d > 0 && d < dd){
dd = int(d-25);
}
d = int(pos.y - w.pos.y);
if (d > 0 && d < ud){
ud = int(d-25);
}
}// y
}// wall size
think();
}/// checkD
void show(){
fill(0,255,0);
rect(pos.x,pos.y,s,s);
}
}
Matrix
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;
}
}
NG
void nextGen(){
for (int i = 0; i < 5; i++){
bs[i] = 0;
be[i] = 0;
}
checkBest();
for (int i = 0; i < total; i++){
enemy.add(PickOne());
}
for (int i = 0; i < 10; i++){
enemy.add(new Enemy(52));
}
checkHigh();
saved.clear();
gen += 1;
}
Enemy PickOne(){
float r = random(4);
r = round(r);
Enemy p = saved.get(be[int(r)]);
Enemy child = new Enemy(52,p.brain);
return child;
}
void checkHigh(){
if (bs[0] > hs){
hs = bs[0];
Enemy e = enemy.get(bs[0]);
e.saveSnake();
}
}
void checkBest(){
for (int i = saved.size()-1; i >= 0; i--){
Enemy e = saved.get(i);
if (e.score > bs[0]){
bs[4] = bs[3];
bs[3] = bs[2];
bs[2] = bs[1];
bs[1] = bs[0];
bs[0] = e.score;
be[4] = be[3];
be[3] = be[2];
be[2] = be[1];
be[1] = be[0];
be[0] = i;
}
else if (e.score > bs[1]){
bs[4] = bs[3];
bs[3] = bs[2];
bs[2] = bs[1];
bs[1] = e.score;
be[4] = be[3];
be[3] = be[2];
be[2] = be[1];
be[1] = i;
}
else if (e.score > bs[2]){
bs[4] = bs[3];
bs[3] = bs[2];
bs[2] = e.score;
be[4] = be[3];
be[3] = be[2];
be[2] = i;
}
else if (e.score > bs[3]){
bs[4] = bs[3];
bs[3] = e.score;
be[4] = be[3];
be[3] = i;
}
else if (e.score > bs[4]){
bs[4] = e.score;
be[4] = i;
}
}
}
Rect I got tired of coding the position over and over
class Rect{
PVector pos;
Rect(int n){
int jj = 0;
while(n > 24){
n -= 25;
jj += 1;
}
pos = new PVector(n * s, jj * s);
}// rect
}
Wall
class Wall extends Rect{
int num = 0;
boolean check = false;
boolean clicked = false;
Wall(int n){
super(n);
num = n;
}// wall
void show(){
fill(255);
if (check){fill(255,255,0);}
rect(pos.x,pos.y,s,s);
fill(0);
textSize(10);
text(num, pos.x + 2, pos.y + 12);
if (clicked){
fill(255,0,0);
ellipse(pos.x+12,pos.y+12,12,12);
}
}// show
void mouseCheck(){
if (mouseX > pos.x && mouseX < pos.x + s &&
mouseY > pos.y && mouseY < pos.y + s){
check = true;
}
else {check = false;}
}
}
end point, the way to win or suppose to be
class endPoint extends Rect{
int num;
endPoint(int n){
super(n);
num = n;
}
void show(){
fill(255,255,0);
rect(pos.x,pos.y,s,s);
fill(0);
text("E",pos.x+5,pos.y+20);
}
}
NN
class NeuralNet {
int iNodes;//No. of input nodes
int hNodes;//No. of hidden nodes
int oNodes;//No. of output nodes
Matrix whi;//matrix containing weights between the input nodes and the hidden nodes
Matrix whh;//matrix containing weights between the hidden nodes and the second layer hidden nodes
Matrix woh;//matrix containing weights between the second hidden layer nodes and the output nodes
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//constructor
NeuralNet(int inputs, int hiddenNo, int outputNo) {
//set dimensions from parameters
iNodes = inputs;
oNodes = outputNo;
hNodes = hiddenNo;
//create first layer weights
//included bias weight
whi = new Matrix(hNodes, iNodes +1);
//create second layer weights
//include bias weight
whh = new Matrix(hNodes, hNodes +1);
//create second layer weights
//include bias weight
woh = new Matrix(oNodes, hNodes +1);
//set the matricies to random values
whi.randomize();
whh.randomize();
woh.randomize();
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//mutation function for genetic algorithm
void mutate(float mr) {
//mutates each weight matrix
whi.mutate(mr);
whh.mutate(mr);
woh.mutate(mr);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//calculate the output values by feeding forward through the neural network
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();
//-----------------------calculate the guessed output
//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();
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//crossover function for genetic algorithm
NeuralNet crossover(NeuralNet partner) {
//creates a new child with layer matrices from both parents
NeuralNet child = new NeuralNet(iNodes, hNodes, oNodes);
child.whi = whi.crossover(partner.whi);
child.whh = whh.crossover(partner.whh);
child.woh = woh.crossover(partner.woh);
return child;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//return a neural net which is a clone of this Neural net
NeuralNet clone() {
NeuralNet clone = new NeuralNet(iNodes, hNodes, oNodes);
clone.whi = whi.clone();
clone.whh = whh.clone();
clone.woh = woh.clone();
return clone;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//converts the weights matrices to a single table
//used for storing the snakes brain in a file
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;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
//takes in table as parameter and overwrites the matrices data for this neural network
//used to load snakes from file
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);
}
}
i’ll show the same but in my try at reinforcement learning in a second