in AI / ML, Hacks

AI / Automate: Flappy Bird

So I had the urge to program something yesterday and somehow decided to take a look at flappy bird. I used a HTML5 version by uralozden. I wanted to write an algorithm that plays flappy bird.

The first idea was to try random moves and record the good ones. But before that I changed the game a bit so that I can get access to the flap() function and interject an AI function. This version of flappy bird is written with Phaser.

Making AI possible

I created a Timer which looks like this:

    aiTimer = new Phaser.Timer(game);
    aiTimer.onEvent.add(randomAI);
    aiTimer.start();
    aiTimer.add(0.2);

In line 2 I insert my function which handles the AI in this case randomAI.

Creating the random AI
The basic idea of the random AI is super easy. Pseudo code looks like this:

If best score > current score:
    use saved moves
else:
    use random moves

I used this approach so that I won’t take forever to get a good enough series of moves. How do we get saved moves? It’s pretty easy. I added code to the score function which works as follows:

if best score > current score:
    do nothing
else:
    best moves = current moves

At that’s basically it. Here you can see at video of the bot playing (started recording mid simulation). It’s a bit laggy but super easy to record thanks to recordit.co:


Using (perfect) information

This version didn’t work so great. The timing was really important. Even if the timer had a few milliseconds lag the bird didn’t make it. You can see this in the video pretty good. The great thing is that we can get access to all the data. Two things would interest us especially. Firstly, the y coordinate of our bird and secondly, the y coordinate of the pipes.

Again I looked around and we can get access to these two data points pretty easily.

birdie.body.y // position of the bird

fingers.forEachAlive(function(finger) {
    finger.y // position of all pipes
}

I don’t want to get into details but Phaser has some internal workings which doesn’t makes it so easy to access the next finger aka. pipe.

The next step was to write a function which controls our height, which basically looks like this:

if(birdie.body.y + offset > goal) {
    flap();
}

Super easy. Nothing special. If we are too low, flap otherwise do nothing. So how does this AI perform? Take a look at the video:

Looks pretty good, eh? I let it run for a while and it stopped because there was an error in the original game which created pipes which were so high that it was impossible to flight through the gap. It was around a score of 99. I’m satisfied.

Write a Comment

Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.