Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions boundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
// 2D Ray Casting
// https://editor.p5js.org/codingtrain/sketches/Nqsq3DFv-

/**
* @tutorial https://www.npmjs.com/package/@types/p5
* @description run npm i @types/p5
*/

/// <reference path="../node_modules/@types/p5/index.d.ts" />
/// <reference path="../node_modules/@types/p5/global.d.ts" />

/// <reference path="./type/p5.d.ts" />

class Boundary {
constructor(x1, y1, x2, y2) {
this.a = createVector(x1, y1);
Expand Down
9 changes: 7 additions & 2 deletions ga.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Daniel Shiffman
// Neuro-Evolution Steering

/// <reference path="./sketch.js" />

function nextGeneration() {
console.log('next generation');
calculateFitness(end);
calculateFitness();
for (let i = 0; i < TOTAL; i++) {
population[i] = pickOne();
}
Expand All @@ -13,6 +15,9 @@ function nextGeneration() {
savedParticles = [];
}

/**
* @returns {Particle}
*/
function pickOne() {
let index = 0;
let r = random(1);
Expand All @@ -28,7 +33,7 @@ function pickOne() {
return child;
}

function calculateFitness(target) {
function calculateFitness() {
for (let particle of savedParticles) {
particle.calculateFitness();
}
Expand Down
6 changes: 5 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand All @@ -9,12 +10,15 @@
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
<title>2D Ray Casting</title>
</head>

<body>
<script src="nn.js"></script>
<script src="ga.js"></script>
<script src="ray.js"></script>
<script src="boundary.js"></script>
<script src="particle.js"></script>
<script src="sketch.js"></script>
<script src="track.js"></script>
</body>
</html>

</html>
25 changes: 22 additions & 3 deletions nn.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
// http://thecodingtrain.com
// https://youtu.be/cdUNkwXx-I4

/**
* @tutorial https://www.npmjs.com/package/@types/p5
* @description run npm i @types/p5
*/
/// <reference path="../node_modules/@types/p5/index.d.ts" />
/// <reference path="../node_modules/@types/p5/global.d.ts" />

///<reference path="type/tensorflow.d.ts"/>
///<reference path="type/p5.d.ts"/>

class NeuralNetwork {
constructor(a, b, c, d) {
if (a instanceof tf.Sequential) {
Expand All @@ -14,10 +24,13 @@ class NeuralNetwork {
this.input_nodes = a;
this.hidden_nodes = b;
this.output_nodes = c;
/**@type {model} */
this.model = this.createModel();
}
}

/**
* copy current weights to new model
*/
copy() {
return tf.tidy(() => {
const modelCopy = this.createModel();
Expand All @@ -30,7 +43,10 @@ class NeuralNetwork {
return new NeuralNetwork(modelCopy, this.input_nodes, this.hidden_nodes, this.output_nodes);
});
}

/**
*
* @param {number} rate
*/
mutate(rate) {
tf.tidy(() => {
const weights = this.model.getWeights();
Expand All @@ -42,6 +58,7 @@ class NeuralNetwork {
for (let j = 0; j < values.length; j++) {
if (random(1) < rate) {
let w = values[j];
// @ts-ignore randomGaussian is wrongly typed in the current version
values[j] = w + randomGaussian();
}
}
Expand All @@ -65,7 +82,9 @@ class NeuralNetwork {
return outputs;
});
}

/**
* @returns {model}
*/
createModel() {
const model = tf.sequential();
const hidden = tf.layers.dense({
Expand Down
33 changes: 32 additions & 1 deletion particle.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/// <reference path="./nn.js" />
/// <reference path="./sketch.js" />
/// <reference path="./ray.js" />

function pldistance(p1, p2, x, y) {
const num = abs((p2.y - p1.y) * x - (p2.x - p1.x) * y + p2.x * p1.y - p2.y * p1.x);
const den = p5.Vector.dist(p1, p2);
return num / den;
}

class Particle {
/**
*
* @param {NeuralNetwork} [brain]
*/
constructor(brain) {
this.fitness = 0;
this.dead = false;
Expand All @@ -15,7 +23,9 @@ class Particle {
this.maxspeed = 5;
this.maxforce = 0.2;
this.sight = SIGHT;
/**@type {Ray[]} */
this.rays = [];
/**@type number */
this.index = 0;
this.counter = 0;

Expand All @@ -41,6 +51,10 @@ class Particle {
this.acc.add(force);
}

/**
* update the position/rotation/velocity of the current particle
* also sets it to dead if it reached its lifespan
*/
update() {
if (!this.dead && !this.finished) {
this.pos.add(this.vel);
Expand All @@ -57,7 +71,10 @@ class Particle {
}
}
}

/**
* @description checks distance to current goal
* @param {Boundary[]} checkpoints
*/
check(checkpoints) {
if (!this.finished) {
this.goal = checkpoints[this.index];
Expand All @@ -79,6 +96,10 @@ class Particle {
// }
}

/**
* @description checks all the rays and executes an action
* @param {Boundary[]} walls
*/
look(walls) {
const inputs = [];
for (let i = 0; i < this.rays.length; i++) {
Expand Down Expand Up @@ -125,12 +146,19 @@ class Particle {
// console.log(output);
}

/**
* @description checks wether the particle in inside the screen
*/
bounds() {
if (this.pos.x > width || this.pos.x < 0 || this.pos.y > height || this.pos.y < 0) {
this.dead = true;
}
}


/**
* @description display the current particle
*/
show() {
push();
translate(this.pos.x, this.pos.y);
Expand All @@ -148,6 +176,9 @@ class Particle {
// }
}

/**
* @description highlights the current particle and its rays in green
*/
highlight() {
push();
translate(this.pos.x, this.pos.y);
Expand Down
17 changes: 14 additions & 3 deletions ray.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@
// 2D Ray Casting
// https://editor.p5js.org/codingtrain/sketches/Nqsq3DFv-

/// <reference path="./sketch.js" />

class Ray {
constructor(pos, angle) {
this.pos = pos;
this.angle = angle;
this.dir = p5.Vector.fromAngle(angle);
}

/**
*
* @param {number} x
* @param {number} y
*/
lookAt(x, y) {
this.dir.x = x - this.pos.x;
this.dir.y = y - this.pos.y;
this.dir.normalize();
}

/**
* @param {number} offset
*/
rotate(offset) {
this.dir = p5.Vector.fromAngle(this.angle + offset);
}
Expand All @@ -29,7 +37,10 @@ class Ray {
line(0, 0, this.dir.x * SIGHT, this.dir.y * SIGHT);
pop();
}

/**
* @param {Boundary} wall
* @returns {import("p5").Vector|null} position of the interception or null
*/
cast(wall) {
const x1 = wall.a.x;
const y1 = wall.a.y;
Expand Down
Loading