In today’s article, I am going to show you various approaches to solving the classic game of Snake with Artificial Intelligence. After the end of this post, you will be able to implement solutions that successfully play the game of Snake.

Perfect game of snake using Hamilton solver

Table of Contents

Game of Snake

Those of you who were raised in the 90’s and before are probably familiar with this classic game and maybe even played it on their first mobile phones.

Game of Snake on Nokia 3310

Anyway, I am still going to briefly introduce you to this game. Snake’s rules are very simple and intuitive.

We are controlling the snake on a rectangular board.

We can turn left, right or continue going forward.

For each fruit we eat, we are scoring a point and our snake gets longer.

We die when we hit a wall (some versions allow going through them) or our snake’s body.

Sound’s easy, right? For us humans it does, but how do we create a program that maximizes the score while taking into consideration above rules?

How to create an AI that plays Snake?

There is no single good answer to this question, so I’ve decided to show you different approaches to solving the game of snake. I have divided the solvers into: Domain Specific (Part 1) and General Purpose (Part 2).

Without going into further details, domain specific solvers aim to maximize the output in a very specific task (weak AI). In order to do so, they can contain:

inputs specific to the environment (in our context - locations of the objects on the grid)

heuristics i.e hardcoded knowledge, shortcuts (in our context - human intuition that pointing towards the fruit is usually a good idea)

In the opposition to the domain specific algorithms, general purpose ones don’t aim for solving narrow tasks. Their goal is to be universal and solve a broader spectrum of problems and maybe someday - reaching or even exceeding human intelligence (Artificial General Intelligence). In order to generalize, they cannot take into consideration any task-specific inputs and heuristics.

AI Research Playground

Before we dive into the algorithms, let’s get more familiar with our Snake implementation. For the purpose of this project, I have developed an AI research playground (Contributions are more than welcome🙂) which is available here. I recommend starting with the instructions provided in the README file.

Each solver (mode) presents a live gameplay preview with stats at the top of the screen, presented in the Score Mode Name (min/avg/max) convention. Whatsmore, you can check ./scores folder for .csv score files and .png plots.

Before starting with the algorithms, I recommend playing Snake yourself.

python slitherin.py --human

Besides entertainment values (it’s fun, isn’t it?), we can get to know the game better and develop strategies to solve the game, usually without even explicitly thinking about it.

An average human player usually starts with a basic policy of pointing the snake towards the fruit in order to maximize the score. Although it’s not an optimal strategy (you’ll later see which one is), it’s a good start.

Domain Specific Solvers

Shortest Path BFS - Breadth First Search

python slitherin.py --shortest_path_bfs

BFS (Breadth First Search) is a graph traversal algorithm and it isn’t the shortest path algorithm per se (if you are more curious you can check and implement Dijkstra or A*), but in our case, it can get a job done.

The algorithm starts at the root node (head of the snake) and explores all neighbor nodes (positions on the grid) at the present depth, before going deeper. It terminates when it finds the fruit.