neuronet-arena
Forty agents, each steered by its own 112-weight neural network, compete for food in a shared arena. The ones that eat the most pass their genes on. Nothing here is a library: the network, the genetic algorithm and the random number generator are written from scratch — first in Python, then ported to the JavaScript running on this page, which reproduces the Python engine bit for bit.
- food
- hazard
- agent
- leader
Click an agent to inspect it, or empty space to follow the leader. Space pauses, N finishes the generation.
Sense
Each agent sees the nearest food and the nearest hazard within 140 px — how close, how far ahead, how far to the right — plus how near the wall in front is and how much energy it has left. Eight numbers, all relative to its own heading.
Think
A network of 8 inputs, 10 hidden neurons and 2 outputs turns those into a steering angle and a throttle. Moving costs energy, food restores it, hazards drain it, and an agent at zero is out for the rest of the generation.
Evolve
After 600 steps the two best genomes are copied unchanged; the rest are bred from tournament winners by uniform crossover and small, roughly Gaussian mutations. In the controlled experiment, the same starting populations with selection switched off stay at about one food per agent.
Same bits
The two engines share a hand-written PRNG, use softsign instead of tanh and turn by Cayley rotation instead of cos/sin, because IEEE 754 defines arithmetic exactly but not transcendental functions. CI replays a golden trace through both and compares every float.
Selection on vs off
Left, the best agents breed, as above. Right, parents are drawn at random and nothing is kept, so fitness is computed but never used. This is the README's controlled experiment, running live; both engines agree on it bit for bit. Its 13.7× is food per agent over the last 10 of 150 generations, across 8 seeds; with selection on, the median passes ten food per agent at generation 23, so the gap takes a while to open.