An AI that learnt to play Flappy Bird

I’ve been watching a lot of videos lately where an AI teaches itself to play a game, mostly Code Bullet’s, like A.I. Learns to DRIVE. Nobody tells it how to play. It just gets better, generation after generation, until it’s better than you. I wanted to know how that actually works, and I’m taking a lot of AI modules at university next year, so I wanted a head start.

So I started with the classic. Tech With Tim has a tutorial series that rebuilds Flappy Bird in Python with pygame and then teaches an AI to play it. I followed it, and today it works.

Evolution, not training

The AI uses NEAT, short for NeuroEvolution of Augmenting Topologies. It doesn’t train one network. It breeds them.

Every generation, 50 birds set off at once, each flown by its own tiny network that starts out random. Most crash straight away. The ones that get furthest have their networks copied, mixed together and changed a little to make the next 50, and the rest die out. Over time NEAT can also add new neurons and links, so the networks grow as they need to.

Each bird only sees three things: how high it is, how far it is from the top pipe, and how far from the bottom one. Its network turns those into one number, and whenever that’s over 0.8, it flaps.

A training run of the game, replayed bird by bird: its first four generations of 50 birds, with the network of whichever bird is in front. The dashed lines are what that bird sees.

The first two generations are hopeless. By the third, one bird gets through nine pipes, and in the fourth, one just doesn’t crash.

What the best bird worked out

NEAT gave the best bird two hidden neurons, but they don’t do anything. Their input is the bird’s height in raw pixels, a number in the hundreds, so they’re always fully on. Take them out and its whole strategy is one rule: flap when you get within about a bird and a half of the bottom pipe. Otherwise, fall.

It’s more or less what I’d do. And nobody told it.

The score decides everything

How a bird gets picked is its score, the fitness. Here it’s simple: a little for every frame it stays alive, 5 for every pipe it gets through, and a point off when it hits one.

It’s not my idea, and most of the code is the tutorial’s, but it’s how I learnt what a fitness function is, and that it decides what the AI ends up doing. The code is on GitHub.

Next I want to try one of my own, with no tutorial: a rocket that learns to land.