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 = [];
|