Last active
July 15, 2022 10:22
-
-
Save LiorB-D/ec291e7bb51d39b48e9d6982fe68ded4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<!-- Load in Tensorflow, P5, and our Car Class--> | |
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script> | |
<script | |
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js" | |
integrity="sha512-WIklPM6qPCIp6d3fSSr90j+1unQHUOoWDS4sdTiR8gxUTnyZ8S2Mr8e10sKKJ/bhJgpAa/qG068RDkg6fIlNFA==" | |
crossorigin="anonymous" | |
></script> | |
<script src="car.js"></script> | |
<script> | |
// Screen dimensions | |
const screenHt = 650; | |
const screenWd = 800; | |
const innerDi = 300; // Diameter of Inner Circle | |
const outerDi = 750; // Diameter of Outer Circle | |
const carDi = 20; // Diameter of each car | |
let currGen = 1; | |
let topFitnessScore = 0; // Highest fitness score of any generation | |
//Obstacles can be added/removed without any additional implementation | |
let obsts = [ | |
{ x: screenWd / 2, y: screenHt / 4, di: 40 }, | |
{ x: screenWd / 2, y: (3 * screenHt) / 4, di: 40 }, | |
]; | |
// UI elements | |
let nextGenBtn, mrateInput, mrateLbl; | |
let infoLbl; | |
let cars = []; | |
function setup() { | |
createCanvas(screenWd + 20 + 200, screenHt + 20); | |
frameRate(60); // Edit Frame Rate to change speed of simulation | |
// Setup UI elements with P5 | |
nextGenBtn = createButton("Next Generation"); | |
nextGenBtn.position(screenWd + 30, 110); | |
mrateInput = createInput("0.15"); | |
mrateInput.position(screenWd + 30, 80); | |
mrateLbl = createElement("p", "Mutation Rate:"); | |
mrateLbl.position(screenWd + 30, 45); | |
infoLbl = createElement( | |
"p", | |
"Gen: " + currGen + ", Top Score: " + topFitnessScore | |
); | |
infoLbl.position(screenWd + 30, 150); | |
// Add 20 new cars | |
for (let i = 0; i < 20; i++) { | |
cars.push(new Car(outerDi, innerDi, screenHt, screenWd, carDi, obsts)); | |
} | |
} | |
function draw() { | |
// Looped based on framerate | |
//Draw Driving Map | |
strokeWeight(1); | |
fill(50); | |
stroke("black"); | |
rect(0, 0, screenWd, screenHt); | |
//Outer Circle | |
fill(210); | |
ellipse(screenWd / 2, screenHt / 2, outerDi, outerDi / 1.5); | |
fill("green"); | |
strokeWeight(3); | |
//Obstacles | |
obsts.forEach((obs) => { | |
ellipse(obs.x, obs.y, obs.di); | |
}); | |
//Inner circle | |
ellipse(screenWd / 2, screenHt / 2, innerDi, innerDi / 2); | |
//Draw Finish Line | |
stroke("red"); | |
strokeWeight(4); | |
line( | |
screenWd / 2 - outerDi / 2, | |
screenHt / 2, | |
screenWd / 2 - innerDi / 2, | |
screenHt / 2 | |
); | |
cars.forEach((car) => { | |
//Draw car | |
//Draw Wheels | |
fill("black"); | |
strokeWeight(0); | |
ellipse( | |
car.x + (carDi / 2) * cos(car.angle + PI / 4), | |
car.y + (carDi / 2) * sin(car.angle + PI / 4), | |
carDi / 2.5 | |
); | |
ellipse( | |
car.x + (carDi / 2) * cos(car.angle - PI / 4), | |
car.y + (carDi / 2) * sin(car.angle - PI / 4), | |
carDi / 2.5 | |
); | |
ellipse( | |
car.x + (carDi / 2) * cos(car.angle + 0.75 * PI), | |
car.y + (carDi / 2) * sin(car.angle + 0.75 * PI), | |
carDi / 2.5 | |
); | |
ellipse( | |
car.x + (carDi / 2) * cos(car.angle - 0.75 * PI), | |
car.y + (carDi / 2) * sin(car.angle - 0.75 * PI), | |
carDi / 2.5 | |
); | |
//Draw Car Base | |
fill("blue"); | |
stroke("black"); | |
strokeWeight(1); | |
ellipse(car.x, car.y, carDi); | |
//Draw Eye | |
fill("yellow"); | |
ellipse(car.eyeX, car.eyeY, carDi / 3); | |
// Car Behavior | |
car.updatePos() | |
}); | |
} | |
</script> | |
<title>Learning to Drive w/ Genetic Algorithm</title> | |
</head> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment