JS_Projects/carDrivingNeuralNet/player.js

139 lines
3.9 KiB
JavaScript
Raw Permalink Normal View History

2022-11-09 23:34:49 +01:00
class Player {
constructor(position) {
this.position = position;
this.rays = [];
this.rawDistances = [];
this.distances = [];
this.fov = 90;
this.angle = 0;
this.acceleration = 2;
this.momentum = createVector(0, 0, 0);
this.velocity = createVector(0, 0, 0);
this.sight = 300;
this.frontalVelocity = 0;
this.maxVel = 12;
this.dead = false;
this.nn = new NeuralNetwork();
this.predictions = [];
this.slow = 0;
this.fitness = 0;
}
show(best) {
let width = 10;
let length = 15;
for (let r of this.rays) {
//r.show();
}
push();
if (!best)
fill(255, 73, 86);
else
fill(66, 129, 255);
noStroke();
translate(this.position.x, this.position.y);
rotate(radians(this.angle));
rect(-width / 2, -length / 2, width, length);
pop();
}
update(vk, hk) {
if (this.distances.length == 9) {
tf.tidy(() => {
this.predictions = this.nn.drive(this.distances);
});
if (this.predictions[0] >= 0) {
hk = '1';
} else {
hk = '0';
}
if (this.predictions[1] >= 0) {
vk = '1';
} else if (this.predictions[1] < 0.25 && this.predictions[1] > -0.25) {
vk = null;
} else {
vk = '0';
}
//print('1: '+this.predictions[0]+' 2: ' + this.predictions[1]);
}
const rotationSpeed = 2.5;
if (hk === '1') {
this.angle += rotationSpeed;
}
if (hk === '0') {
this.angle -= rotationSpeed;
}
if (vk == '1') {
this.velocity = p5.Vector.fromAngle(radians(this.angle - 90), 1);
this.momentum.mult(0.975);
} else if (vk == '0') {
this.velocity = createVector(0, 0, 0);
this.momentum.mult(0.9);
} else {
this.velocity = createVector(0, 0, 0);
this.momentum.mult(0.95);
}
if (this.momentum.mag() < 0.1) {
this.slow++;
}
if (this.slow > 15) {
this.dead = true;
}
if (!this.dead) {
this.fitness++;
}
//this.momentum = (this.momentum.sub(this.momentum.mult(0.00001)));
this.momentum.add(this.velocity.mult(0.12));
this.momentum.limit(this.maxVel);
this.position.add(this.momentum);
this.rays = [];
for (let i = -180; i < 180; i += 45) {
this.rays.push(new Ray(this.position.x, this.position.y, radians(i + this.angle), this.sight));
}
for (let r of this.rays) {
for (let w of walls) {
r.cast(w);
}
//r.show();
}
this.rawDistances = [];
for (let i = 0; i < this.rays.length; i++) {
this.rawDistances[i] = this.rays[i].cast();
if (this.rawDistances[i] != null && this.rawDistances[i] < 10)
this.dead = true;
}
this.frontalVelocity = map(this.momentum.mag(), 0, 5, 0, 1);
this.distances = getDistances(this.rawDistances, this.rawDistances.length, this.sight);
this.distances.push(this.frontalVelocity);
}
}
function angleToVector(xCoord, yCoord, angle, length) {
length = typeof length != 'undefined' ? length : 10;
angle = angle * Math.PI / 180; // if you're using degrees instead of radians
return createVector(length * Math.cos(angle) + xCoord, length * Math.sin(angle) + yCoord);
}
function getDistances(distances, l, sight) {
let array = [];
let length = l;
for (let i = 0; i < length; i++) {
if (distances[i] == null)
array[i] = 0;
else
array[i] = map(distances[i], 10, sight, 1, 0);
}
return array;
}