A neural network learns to play snakes
Built with Rust and Macroquad game engine
Tab
- Enable/Disable visualizationSpace
- Slow down the simulation
- Neuro-evolution: A subfield of artificial intelligence and evolutionary computation that uses evolutionary algorithms to evolve artificial neural networks.
- Genetic Algorithm (GA): An optimization algorithm inspired by the process of natural selection and genetics, used to evolve populations of solutions to optimization problems
- Population: A collection of individuals (neural networks) that are subject to evolution in a neuro-evolutionary algorithm.
- Island Model: A technique in neuro-evolution where multiple separate populations (islands, in code this is called streams) of individuals evolve independently, periodically exchanging individuals between islands to maintain diversity and promote exploration.
- Mutation: The process of introducing random changes to the genetic material (weights, biases, or network structure) of individuals in the population. Mutation helps introduce new variations and explore the solution space
- Every snake has a neural network that acts as its brain.
- The snake can see in 4 direction. It can detect food, wall and itself in these 4 directions. Total number of inputs =
4 * 3 = 12
- These 12 values are fed as an input to the neural network. The neural network then generates 4 values that indicate the threshold for actions - left, right, bottom and top.
- Every generation has 5 streams (islands) of 1000 snakes each. The snakes in each stream evolve independently of the snakes from other streams
- Occasionally best performing snakes from one stream are injected into another. This technique is called "Island Rejuvenation".
- The simulation begins at
Generation 0
with 5 streams of games, the individuals in each of these streams have randomly generated neural networks. - Each step, we update every game i.e pass the vision inputs to the neural network and have it decide on an action to take.
- When the snake collides the walls or when it collides with itself, the game is flagged as completed.
- Aditionally, games are marked complete when the snake isn't able to eat food for a certain number of steps. This is to prevent snakes from performing looping actions indefinitely.
- We update each game in a generation until all the games are complete.
- At the end of each generation, each snake in a stream is ranked based on how it performed.
- Based on this ranking, parents are chosen for the next batch of snakes. Snake at rank 1 is more probable to be a parent compared to snake at rank 10.
- Here's an example of how the population is distributed throughout every generation:
- Top 1% of the snakes are retained for next generation
- 50% of the population is newly generated using 2 snakes from the previous generation as their parents
- 20% of the snakes are freshly generated with no connection to the past generations
- The rest 29% of the population are all mutations of the current best performing snakes
- Once we have a new population, we start a new generation. And the above steps are performed until the simulation is closed manually.
- The above steps result in the snakes fine tuning their strategies which inturn lead to longer snakes.
- Clone the repo
git clone git@github.com:bones-ai/rust-snake-ai.git
cd rust-snake-ai
- Run the simulation
cargo run --release
- The project config file is located at
src/configs.rs
- Disable
VIZ_DARK_THEME
changes the theming - The streams feature is still experimental. A single stream with 1000 snakes will yield quick results.