racing-AI
A hundred cars that cannot see the track, evolving until they can drive it.

The story
I saw a video about evolving controllers by breeding and mutation, and I wanted to see for myself whether something that simple really works. It does. A hundred cars start with random numbers in their heads and drive into a wall. The few that get furthest are copied, mixed and slightly mutated, and their children try again. Nobody shows them a good lap: there is no dataset, only survival.
- weights in each brain
- 470
- generations of evolution
- 300
- unseen tracks out of 40 finished without a crash
- 40
- average lap on those tracks
- 27.7 s
What the car is allowed to see
This is the choice everything else depends on. Each car gets eight numbers: seven distances to the walls, cast like rays, and its own speed. No map and no idea where it is on the track, so it cannot learn a layout by heart. Whatever it ends up doing has to be actual driving.
The brain is a small network, 8 → 16 → 12 → 8 → 2, and its two outputs are the steering and the pedal. All 470 of its weights, laid end to end, are the car's genome.
- 1
Race
Every car drives six tracks generated for this generation alone. No layout is ever seen twice, and the tracks used to judge the champion come from a separate range of seeds.
- 2
Score
Finishing is a gate, not a bonus: a car that completes the lap always outranks one that does not, so lap time can never be bought with risk. Across the six tracks the score is 70% the average and 30% the worst, so consistency beats one lucky run.
- 3
Breed
The best 5 pass on untouched. The rest are children of the top 25, picked by tournaments of three, mixed gene by gene and mutated slightly. 3 random newcomers join every generation so the population never collapses on one idea.
- 4
Repeat
The mutation shrinks a little every generation, from wide exploration early on to fine tuning at the end.
From the wall to the finish line
In generation zero, almost every car crashes or goes nowhere: half a percent of the runs finish a lap. By the last fifty generations, 82% of them do, on tracks the cars had never seen until that moment.
Braking that nobody rewarded
The physics decide what driving means here. Below about 4 units per second the steering is limited by the rack; above it, by grip, so the turning radius grows with the square of the speed. At top speed the car needs a radius of about 84 units, and the generated corners go down to about 19.
So a corner cannot be taken flat out. Nothing in the score mentions braking, and the cars learned to brake anyway, because it was the only way through a hairpin.
Picking the champion
Scores cannot be compared across generations, because the tracks change underneath them. So the saved driver is not the one with the highest score. Every ten generations the current leader races on tracks kept aside for this, and it replaces the champion only if it finishes more of them, with lap time as the tie-break. The final champion finishes all 40 without a crash, at 27.7 seconds a lap on average.
Fast enough to try things
The whole population is one set of NumPy arrays: one raycast call and one forward pass for a hundred cars at once. A generation over six tracks takes about 8 seconds on a laptop, which is what makes a 300-generation run cheap enough to try ideas on.
A run is reproducible to the byte: training with the window open and headless from the same seed produce identical populations, and resuming a run picks up the same random stream. 114 tests keep it that way.
Gallery

Want something like this?
I can build the same thing for your product.
Tell me what you have in mind. You get an answer the same day, with a realistic scope and timeline, not a sales pitch.