Add 1 files
Browse files- index.html +78 -25
index.html
CHANGED
|
@@ -69,7 +69,7 @@
|
|
| 69 |
Pause
|
| 70 |
</button>
|
| 71 |
<button id="resetBtn" class="bg-red-600 hover:bg-red-700 px-3 py-1 rounded text-sm">
|
| 72 |
-
|
| 73 |
</button>
|
| 74 |
</div>
|
| 75 |
</div>
|
|
@@ -109,12 +109,13 @@
|
|
| 109 |
<div class="bg-gray-800 p-4 rounded-lg sticky top-4">
|
| 110 |
<h3 class="font-semibold text-blue-300 mb-3">How It Works</h3>
|
| 111 |
<div class="text-sm space-y-3 text-gray-300">
|
| 112 |
-
<p>This simulation demonstrates how AI can learn to drive through
|
| 113 |
|
| 114 |
-
<p>Each
|
| 115 |
|
| 116 |
<p>Key components:</p>
|
| 117 |
<ul class="list-disc pl-5 space-y-1">
|
|
|
|
| 118 |
<li><span class="font-medium">Sensors:</span> 5 distance sensors (front, left, right, front-left, front-right)</li>
|
| 119 |
<li><span class="font-medium">Neural Network:</span> 5 inputs, 1 hidden layer (6 neurons), 2 outputs (left/right)</li>
|
| 120 |
<li><span class="font-medium">Fitness:</span> Based on distance traveled and checkpoints reached</li>
|
|
@@ -122,7 +123,7 @@
|
|
| 122 |
</ul>
|
| 123 |
|
| 124 |
<div class="pt-2 border-t border-gray-700 mt-4">
|
| 125 |
-
<p class="text-xs text-gray-400">Watch as the AI
|
| 126 |
</div>
|
| 127 |
</div>
|
| 128 |
</div>
|
|
@@ -166,30 +167,78 @@
|
|
| 166 |
walls: [],
|
| 167 |
checkpoints: [],
|
| 168 |
startPosition: { x: 100, y: 250, angle: 0 },
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
this.walls = [
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
{ x:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
-
//
|
| 186 |
-
|
| 187 |
-
{ x: 700, y: 100,
|
| 188 |
-
{ x: 600, y: 400,
|
| 189 |
-
{ x: 300, y: 400
|
| 190 |
-
{ x: 100, y: 300,
|
|
|
|
|
|
|
|
|
|
| 191 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
},
|
|
|
|
| 193 |
draw(ctx) {
|
| 194 |
// Draw walls
|
| 195 |
ctx.fillStyle = '#4a5568';
|
|
@@ -529,6 +578,9 @@
|
|
| 529 |
const startTime = performance.now();
|
| 530 |
generation++;
|
| 531 |
generationCount.textContent = generation;
|
|
|
|
|
|
|
|
|
|
| 532 |
|
| 533 |
// Calculate fitness
|
| 534 |
calculateFitness();
|
|
@@ -617,7 +669,8 @@
|
|
| 617 |
|
| 618 |
// Initialize simulation
|
| 619 |
function init() {
|
| 620 |
-
track
|
|
|
|
| 621 |
|
| 622 |
// Create initial population
|
| 623 |
cars = [];
|
|
|
|
| 69 |
Pause
|
| 70 |
</button>
|
| 71 |
<button id="resetBtn" class="bg-red-600 hover:bg-red-700 px-3 py-1 rounded text-sm">
|
| 72 |
+
New Track
|
| 73 |
</button>
|
| 74 |
</div>
|
| 75 |
</div>
|
|
|
|
| 109 |
<div class="bg-gray-800 p-4 rounded-lg sticky top-4">
|
| 110 |
<h3 class="font-semibold text-blue-300 mb-3">How It Works</h3>
|
| 111 |
<div class="text-sm space-y-3 text-gray-300">
|
| 112 |
+
<p>This simulation demonstrates how AI can learn to drive through randomly generated courses using a genetic algorithm.</p>
|
| 113 |
|
| 114 |
+
<p>Each time you click "New Track", the course layout and checkpoint locations are randomized. This forces the AI to develop general driving skills rather than memorizing a specific track.</p>
|
| 115 |
|
| 116 |
<p>Key components:</p>
|
| 117 |
<ul class="list-disc pl-5 space-y-1">
|
| 118 |
+
<li><span class="font-medium">Random Tracks:</span> Procedurally generated with varying complexity</li>
|
| 119 |
<li><span class="font-medium">Sensors:</span> 5 distance sensors (front, left, right, front-left, front-right)</li>
|
| 120 |
<li><span class="font-medium">Neural Network:</span> 5 inputs, 1 hidden layer (6 neurons), 2 outputs (left/right)</li>
|
| 121 |
<li><span class="font-medium">Fitness:</span> Based on distance traveled and checkpoints reached</li>
|
|
|
|
| 123 |
</ul>
|
| 124 |
|
| 125 |
<div class="pt-2 border-t border-gray-700 mt-4">
|
| 126 |
+
<p class="text-xs text-gray-400">Watch as the AI learns to navigate completely new tracks!</p>
|
| 127 |
</div>
|
| 128 |
</div>
|
| 129 |
</div>
|
|
|
|
| 167 |
walls: [],
|
| 168 |
checkpoints: [],
|
| 169 |
startPosition: { x: 100, y: 250, angle: 0 },
|
| 170 |
+
|
| 171 |
+
generateRandomTrack() {
|
| 172 |
+
this.walls = [];
|
| 173 |
+
this.checkpoints = [];
|
| 174 |
+
|
| 175 |
+
// Outer boundary walls (always present)
|
| 176 |
+
this.walls.push(
|
| 177 |
+
{ x: 50, y: 50, width: 700, height: 20 }, // top
|
| 178 |
+
{ x: 50, y: 50, width: 20, height: 400 }, // left
|
| 179 |
+
{ x: 50, y: 430, width: 700, height: 20 }, // bottom
|
| 180 |
+
{ x: 730, y: 50, width: 20, height: 400 } // right
|
| 181 |
+
);
|
| 182 |
+
|
| 183 |
+
// Generate random obstacles (between 3-8 obstacles)
|
| 184 |
+
const obstacleCount = 3 + Math.floor(Math.random() * 6);
|
| 185 |
+
for (let i = 0; i < obstacleCount; i++) {
|
| 186 |
+
const isVertical = Math.random() > 0.5;
|
| 187 |
+
let x, y, width, height;
|
| 188 |
|
| 189 |
+
if (isVertical) {
|
| 190 |
+
width = 20;
|
| 191 |
+
height = 50 + Math.random() * 200;
|
| 192 |
+
x = 100 + Math.random() * 600;
|
| 193 |
+
y = 100 + Math.random() * (400 - height);
|
| 194 |
+
} else {
|
| 195 |
+
width = 50 + Math.random() * 200;
|
| 196 |
+
height = 20;
|
| 197 |
+
x = 100 + Math.random() * (700 - width);
|
| 198 |
+
y = 100 + Math.random() * 300;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
// Make sure obstacle doesn't block the start position
|
| 202 |
+
if (!(x < 150 && y < 300 && y + height > 200)) {
|
| 203 |
+
this.walls.push({ x, y, width, height });
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
// Generate checkpoints (3-5 checkpoints)
|
| 208 |
+
const checkpointCount = 3 + Math.floor(Math.random() * 3);
|
| 209 |
+
const checkpointSize = 30;
|
| 210 |
|
| 211 |
+
// Generate positions that require navigating around obstacles
|
| 212 |
+
const possiblePositions = [
|
| 213 |
+
{ x: 700, y: 100 }, // right side top
|
| 214 |
+
{ x: 600, y: 400 }, // middle right bottom
|
| 215 |
+
{ x: 300, y: 400 }, // middle bottom
|
| 216 |
+
{ x: 100, y: 300 }, // left side middle
|
| 217 |
+
{ x: 400, y: 100 }, // middle top
|
| 218 |
+
{ x: 200, y: 200 }, // middle left
|
| 219 |
+
{ x: 600, y: 200 } // middle right
|
| 220 |
];
|
| 221 |
+
|
| 222 |
+
// Shuffle and take first checkpointCount positions
|
| 223 |
+
const shuffled = [...possiblePositions].sort(() => 0.5 - Math.random());
|
| 224 |
+
for (let i = 0; i < checkpointCount; i++) {
|
| 225 |
+
const pos = shuffled[i];
|
| 226 |
+
this.checkpoints.push({
|
| 227 |
+
x: pos.x,
|
| 228 |
+
y: pos.y,
|
| 229 |
+
width: checkpointSize,
|
| 230 |
+
height: checkpointSize
|
| 231 |
+
});
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
// Set start position (always left side, but random vertical position)
|
| 235 |
+
this.startPosition = {
|
| 236 |
+
x: 100,
|
| 237 |
+
y: 100 + Math.random() * 300,
|
| 238 |
+
angle: 0
|
| 239 |
+
};
|
| 240 |
},
|
| 241 |
+
|
| 242 |
draw(ctx) {
|
| 243 |
// Draw walls
|
| 244 |
ctx.fillStyle = '#4a5568';
|
|
|
|
| 578 |
const startTime = performance.now();
|
| 579 |
generation++;
|
| 580 |
generationCount.textContent = generation;
|
| 581 |
+
|
| 582 |
+
// lunarflu
|
| 583 |
+
track.generateRandomTrack();
|
| 584 |
|
| 585 |
// Calculate fitness
|
| 586 |
calculateFitness();
|
|
|
|
| 669 |
|
| 670 |
// Initialize simulation
|
| 671 |
function init() {
|
| 672 |
+
// Generate random track
|
| 673 |
+
track.generateRandomTrack();
|
| 674 |
|
| 675 |
// Create initial population
|
| 676 |
cars = [];
|