Solo Project Simulation AI Algorithm

Racecar Evolution

Timeframe: 1 Month
Role: Designer and Developer
Tools: Unity, Visual Studio
Skills: C#

An interactive simulation showcasing a genetic algorithm of a racecar learning to drive on a track. Users first create a looped racetrack using the built-in track creator, then once they hit play the simulation will start. During the simulation, batches of racecar AI are placed into the simulation in generations. Each racecar agent starts with a randomized set of instructions to complete the track, and as each generation ends a new generation is made by "evolving" the previous generation. This means selecting a certain number cars that had the best run and using their set of instructions or "chromosome" as the basis of the new generation. This process is set to continue until an agent is found who completed the track at a high level of quality. This project was my introduction to genetic algorithms and can certainly be improved, but remains a good display of the algorithm's process and adaptability.

What makes all of this work is the fitness function which is able to calculate how well each racecar agent did in their run of the track. This drives the process of evolution and also determines when the simulation is finished. Creating, testing, and improving the fitness function was one of the major challenges of the whole project. I tried using average speed, track completion time, percentage of run within track boundaries, percentage of track visited, and a completion check all as weighted variables that would add up to calculate the overall fitness. In the end, I chose to use the inside boundaries percentage, track visitation percentage, and a completion check to make up the entire calculation.

There's no denial that speed and lap time, as well as many other possible statistics, are just as important, but too many unwanted behaviors arose when prioritizing these variables. Racers would be able to achieve very high speeds by not turning often and going way out of the boundaries of the track and racers would be able to achieve very low lap times by looping the starting line and going past it again as a finish line. Unfortunately, most of these problems derive from my desire for the algorithm to adapt from a starting point of complete freedom. While the track is visible to the users, it means nothing to the AI as its doing its run. If the racetrack was a physical object and restricted the racers inside of the road area with bounding walls at the edges, then most unwanted behvior I was getting would have been stopped from the start.

In the end, most of this project's flaws come from it trying to adapt and accomodate to any possible racetrack that can be created in the simulation. I was overly ambitious and overestimated the power of genetic algorithms thinking that they would work the same on all possible tracks it would be presented with. But at the same time, with some additional tweaking I feel the simulation can be greatly improved and be able to actually generate a quality racer that can complete most tracks you give it.

    Challenges:
  • Figuring out a proper way to represent the chromosome of each racer in code
  • Creating, testing, and improving the fitness function to be as effective as possible
  • Building a comprehensive track creator that manages all the necessary track data for the simulation as the track is being built
  • Adjusting the algorithm to see good results on multiple different racetracks rather than the few the algorithm was tested on

    What I did well:
  • The tile-based track creator allows users to run the simulation on any track they can think of
  • Each racer agent has a list of actions that automatically play and link into each other as the simulation runs
  • The simulation can be sped up or slowed down for convenience without affecting the result of each generation
  • Each wave of racers is visually displayed in an interesting and easy to follow way

    What I would change/improve:
  • Adapt starting chromosome sizes based on the length of the racetrack
  • Restrict the racers to only be able to drive within the racetrack
  • Incoportate speed and lap time variables back into the fitness evaluation
  • Further refine mutation and selection mechanics