xxxxxxxxxx
128
class Snake
{
constructor(t)
{
if (t != 1)
this.weights = [random(-1, 1), random(-1, 1), random(-1, 1)];
// FORWARD RIGHT LEFT
else this.weights = [];
this.fitness = 0;
this.grid = [];
for (let i = 0; i < width/scl + 2; i++)
{
this.grid.push([]);
for (let j = 0; j < height/scl + 2; j++)
this.grid[i].push((i == 0 || j == 0 || i == width/scl + 1 || j == height/scl + 1) ? 0 : 1);
}
this.dir = createVector(-1, 0);
this.pointer = 2;
this.dead = false;
this.pos = createVector(4, 4);
this.tail = [createVector(5 * scl + scl / 2, 4 * scl + scl / 2), createVector(6 * scl + scl / 2, 4 * scl + scl / 2), createVector(7 * scl + scl / 2, 4 * scl + scl / 2)];
{
this.grid[4+1][4+1] = 0;
this.grid[5+1][4+1] = 0;
this.grid[6+1][4+1] = 0;
this.grid[7+1][4+1] = 0;
}
}
display()
{
noStroke();
fill(200);
ellipse(this.pos.x * scl + scl / 2, this.pos.y * scl + scl / 2, segmSize);
for (let segm of this.tail)
ellipse(segm.x, segm.y, segmSize);
// for (let i = 0; i < width/scl + 2; i++)
// for (let j = 0; j < height/scl + 2; j++)
// if (this.grid[i][j] == 0)
// {
// push();
// fill(0,255,0);
// rect(i*scl-scl, j*scl-scl, scl, scl);
// pop();
// }
}
move(dir)
{
let temp = this.tail.pop();
temp.x = (temp.x - scl / 2) / scl;
temp.y = (temp.y - scl / 2) / scl;
this.grid[temp.x+1][temp.y+1] = 1;
this.tail.unshift(createVector(this.pos.x * scl + scl / 2, this.pos.y * scl + scl / 2));
switch (dir)
{
case 0:
break;
case 1:
if (this.dir.x == 1) {this.dir.set(0, 1); this.pointer = 1}
else if (this.dir.x == -1) {this.dir.set(0, -1); this.pointer = 3}
else if (this.dir.y == 1) {this.dir.set(-1, 0); this.pointer = 2}
else if (this.dir.y == -1) {this.dir.set(1, 0); this.pointer = 0}
break;
case -1:
if (this.dir.x == 1) {this.dir.set(0, -1); this.pointer = 3}
else if (this.dir.x == -1) {this.dir.set(0, 1); this.pointer = 1}
else if (this.dir.y == 1) {this.dir.set(1, 0); this.pointer = 0}
else if (this.dir.y == -1) {this.dir.set(-1, 0); this.pointer = 2}
break;
}
this.pos.add(this.dir);
this.grid[this.pos.x+1][this.pos.y+1] = 0;
this.dead = (this.pos.x <= 0 || this.pos.y <= 0 || this.pos.x >= wEdge || this.pos.y >= hEdge);
}
decide()
{
if (this.dead) return 0;
let val;
switch(this.pointer)
{
case 0:
val = this.weights[0] * this.grid[this.pos.x + 2][this.pos.y + 1] +
this.weights[1] * this.grid[this.pos.x + 1][this.pos.y + 2] +
this.weights[2] * this.grid[this.pos.x + 1][this.pos.y ];
break;
case 1:
val = this.weights[0] * this.grid[this.pos.x + 1][this.pos.y + 2] +
this.weights[1] * this.grid[this.pos.x ][this.pos.y + 1] +
this.weights[2] * this.grid[this.pos.x + 2][this.pos.y + 1];
break;
case 2:
val = this.weights[0] * this.grid[this.pos.x ][this.pos.y + 1] +
this.weights[1] * this.grid[this.pos.x + 1][this.pos.y ] +
this.weights[2] * this.grid[this.pos.x + 1][this.pos.y + 2];
break;
case 3:
val = this.weights[0] * this.grid[this.pos.x + 1][this.pos.y ] +
this.weights[1] * this.grid[this.pos.x + 2][this.pos.y + 1] +
this.weights[2] * this.grid[this.pos.x ][this.pos.y + 1];
break;
}
val = round(Math.tanh(val));
this.move(val);
}
checkFitness()
{
if (this.dead) this.fitness = 0;
else this.fitness = this.tail.length;
return this.fitness;
}
}