Training an Asteroids Agent With a Neural Network and Genetic Algorithm
This project was an experiment in combining a neural network with a genetic algorithm to train an agent that can play Asteroids. I built the game environment in JavaScript with p5.js, then modified it so the ship could be controlled by an AI agent instead of only keyboard input.
The goal was not just to make an Asteroids clone, but to create a small learning system where agents could survive longer and improve their behavior over generations.
Building the Game Environment
I started by creating a playable Asteroids game. The player ship could rotate left and right, accelerate forward, shoot, and avoid incoming asteroids.
After the basic game was working, I changed the control structure so these same actions could be selected by the computer. This turned the game from a player-controlled environment into a training environment for agents.
The available actions were:
- Turn right
- Turn left
- Accelerate forward
- Shoot
- Do nothing
This gave the agent a small but meaningful action space. It had enough control to survive and destroy asteroids, but the problem was still simple enough to experiment with directly.
Designing the Neural Network
To decide which action to take, I designed a neural network that received information about the ship’s surroundings.
The input layer used 16 values. Each value represented the distance to asteroids in a different direction around the ship. This worked like a simple radar system. Instead of giving the agent the full game state, I gave it directional information about nearby threats.
The network structure was:
- 16 input neurons
- 2 hidden layers with 12 neurons each
- 5 output neurons
The 5 outputs corresponded to the possible actions the ship could take.
I also tested different activation functions. With sigmoid, I noticed that the ship was more likely to repeat the same action continuously. ReLU produced better behavior in my tests, so I used it for the final version.
Evolving the Agent
After the neural network was working, I added the genetic algorithm.
Each ship in the population had its own neural network weights. At the beginning, these weights were random, so the ships behaved randomly as well. Some survived longer or destroyed more asteroids by chance, and those agents received better fitness scores.
The fitness score was based on:
- The ship’s survival order within the population
- The number of asteroids destroyed
- How often the ship moved forward
This scoring system encouraged agents to survive, shoot asteroids, and avoid staying passive.
Crossover and Mutation
After each generation, better-performing ships had a higher chance of passing their neural network weights to the next generation.
For crossover, I combined the weights of two parent ships by mixing their neuron values. Some parts of the child network were closer to the first parent, while other parts were closer to the second parent.
For mutation, I randomly changed selected neuron values in the network. This gave the population a way to discover new behaviors instead of only repeating the same patterns.
This process made the project feel more like an artificial evolution experiment than a traditional training system.
Watching the Agents Learn
One of the most interesting parts of the project was watching the agents behave inside the game. Since the environment was visual, I could directly observe how ships moved, failed, survived, or repeated bad habits.
Some agents would drift into asteroids immediately. Some would spin or keep repeating the same action. Others would survive longer by chance, and those behaviors could become more common in the next generations.
This made the learning process easier to understand because I was not only looking at numbers. I could see the behavior behind the training process.
Challenges
The biggest challenge was performance.
As the population size increased, the simulation became much slower. Even though I was only visualizing one population member, many agents still had to be simulated in the background. Because of that, training took more time and it became harder to quickly observe problems, adjust the code, and test again.
The system was tested with a population size of 50, but the agents did not develop enough behavioral diversity at that size. Many ships started acting similarly, which limited the learning process.
This showed me one of the practical problems of evolutionary algorithms: larger populations can explore more behaviors, but they also cost much more to simulate.
What I Learned
This project helped me understand neural networks and genetic algorithms from a low-level, experimental perspective. I was not only using the terms “network,” “fitness,” “crossover,” and “mutation”; I had to make each part work inside an actual game loop.
I also learned that the design of the inputs matters a lot. Giving the agent 16 directional distance values was a simple way to describe the environment, but it also limited how much the agent could understand. The behavior of the system depended not only on the algorithm, but also on how the game state was represented.
Final Thoughts
This was a small project, but it was an important step in learning how AI systems can interact with games. It connected game development, neural network behavior, genetic algorithms, and real-time visualization in one experiment.
The final result was not a fully optimized Asteroids-playing AI, but it helped me understand the full pipeline of creating an environment, designing agent inputs and outputs, scoring behavior, evolving networks, and observing the results.
Sinir Ağı ve Genetik Algoritma ile Bir Asteroids Ajanı Eğitmek
Bu proje, Asteroids oynayabilen bir ajan eğitmek için sinir ağı ile genetik algoritmayı bir araya getirdiğim deneysel bir çalışmaydı. Oyun ortamını JavaScript ve p5.js kullanarak geliştirdikten sonra geminin yalnızca klavye girdileriyle değil, bir yapay zeka ajanı tarafından da kontrol edilebilmesini sağladım.
Amacım hem bir Asteroids klonu geliştirmek hem de ajanların nesiller boyunca daha uzun süre hayatta kalabildiği ve davranışlarını geliştirebildiği küçük bir öğrenme sistemi oluşturmaktı.
Oyun Ortamını Oluşturmak
İlk olarak oynanabilir bir Asteroids oyunu geliştirdim. Oyuncunun kontrol ettiği gemi sağa ve sola dönebiliyor, ileri doğru hızlanabiliyor, ateş edebiliyor ve yaklaşan asteroitlerden kaçabiliyordu.
Oyunun temel yapısı tamamlandıktan sonra kontrol sistemini değiştirerek aynı eylemlerin bilgisayar tarafından seçilebilmesini sağladım. Böylece oyuncu tarafından kontrol edilen oyun, ajanların eğitilebildiği bir ortama dönüştü.
Ajanın kullanabileceği eylemler şunlardı:
- Sağa dönmek
- Sola dönmek
- İleri doğru hızlanmak
- Ateş etmek
- Hiçbir şey yapmamak
Bu yapı, ajana küçük ancak anlamlı bir eylem uzayı sağladı. Gemi, hayatta kalmak ve asteroitleri yok etmek için yeterli kontrole sahipti. Aynı zamanda problem doğrudan deneyler yapabileceğim kadar basit kalıyordu.
Sinir Ağını Tasarlamak
Ajanın hangi eylemi gerçekleştireceğine karar vermesi için geminin çevresi hakkında bilgi alan bir sinir ağı tasarladım.
Girdi katmanında 16 değer bulunuyordu. Her değer, geminin çevresindeki farklı bir yönde bulunan asteroitlere olan mesafeyi temsil ediyordu. Bu sistem basit bir radar gibi çalışıyordu. Ajana oyunun tüm durumunu vermek yerine yakınındaki tehditler hakkında yönsel bilgiler sağladım.
Ağın yapısı şu şekildeydi:
- 16 girdi nöronu
- Her birinde 12 nöron bulunan 2 gizli katman
- 5 çıktı nöronu
Beş çıktı, geminin gerçekleştirebileceği eylemlere karşılık geliyordu.
Farklı aktivasyon fonksiyonlarını da test ettim. Sigmoid kullandığımda geminin aynı eylemi sürekli tekrar etmeye daha yatkın olduğunu gözlemledim. ReLU, yaptığım testlerde daha iyi davranışlar ürettiği için son sürümde bu fonksiyonu kullandım.
Ajanı Evrimleştirmek
Sinir ağı çalışmaya başladıktan sonra sisteme genetik algoritmayı ekledim.
Popülasyondaki her gemi kendine ait sinir ağı ağırlıklarına sahipti. Başlangıçta bu ağırlıklar rastgele belirlendiği için gemiler de rastgele davranıyordu. Bazı ajanlar tesadüfen daha uzun süre hayatta kalıyor veya daha fazla asteroit yok ediyor, bunun sonucunda daha yüksek uygunluk puanları alıyordu.
Uygunluk puanı şu ölçütlere göre hesaplanıyordu:
- Geminin popülasyon içindeki hayatta kalma sırası
- Yok ettiği asteroit sayısı
- Ne sıklıkla ileri doğru hareket ettiği
Bu puanlama sistemi, ajanları hayatta kalmaya, asteroitlere ateş etmeye ve hareketsiz kalmamaya teşvik ediyordu.
Çaprazlama ve Mutasyon
Her neslin sonunda daha iyi performans gösteren gemilerin sinir ağı ağırlıklarını sonraki nesle aktarma ihtimali daha yüksek oluyordu.
Çaprazlama sırasında iki ebeveyn geminin ağırlıklarını, nöron değerlerini karıştırarak birleştirdim. Oluşan yeni ağın bazı bölümleri ilk ebeveyne, diğer bölümleri ise ikinci ebeveyne daha yakın oluyordu.
Mutasyon sırasında ise ağdaki seçili nöron değerlerini rastgele değiştirdim. Bu yöntem, popülasyonun yalnızca aynı davranış kalıplarını tekrarlamak yerine yeni davranışlar keşfedebilmesini sağlıyordu.
Bu süreç, projeyi geleneksel eğitim sisteminden farklı olan bir evrim deneyine dönüştürdü.
Ajanların Öğrenmesini İzlemek
Projenin en ilgi çekici bölümlerinden biri, ajanların oyun içindeki davranışlarını izlemekti. Ortam görsel olduğu için gemilerin nasıl hareket ettiğini, başarısız olduğunu, hayatta kaldığını veya hatalı davranışları tekrar ettiğini doğrudan gözlemleyebiliyordum.
Bazı ajanlar anında asteroitlere çarpıyordu. Bazıları kendi etrafında dönüyor veya sürekli aynı eylemi tekrarlıyordu. Diğerleri ise tesadüfen daha uzun süre hayatta kalıyor ve bu davranışlar sonraki nesillerde daha yaygın hâle gelebiliyordu.
Bu durum öğrenme sürecini anlamayı kolaylaştırdı çünkü yalnızca sayısal sonuçları incelemiyordum. Eğitimin arkasındaki davranışları doğrudan görebiliyordum.
Karşılaştığım Zorluklar
Projedeki en büyük zorluk performanstı.
Popülasyon boyutu arttıkça simülasyon önemli ölçüde yavaşlıyordu. Ekranda yalnızca bir popülasyon üyesini göstermeme rağmen diğer ajanların da arka planda simüle edilmesi gerekiyordu. Bu nedenle eğitim daha uzun sürüyor, sorunları gözlemlemek, kodu düzenlemek ve yeniden test etmek zorlaşıyordu.
Sistemi 50 ajanlık bir popülasyonla test ettim ancak bu boyutta ajanlar yeterli davranış çeşitliliği geliştiremedi. Birçok gemi benzer şekilde davranmaya başladı ve bu durum öğrenme sürecini sınırladı.
Bu deneyim, evrimsel algoritmaların pratik sorunlarından birini gösterdi. Daha büyük popülasyonlar daha fazla davranışı keşfedebiliyordu ancak simülasyon maliyetleri de önemli ölçüde artıyordu.
Öğrendiklerim
Bu proje, sinir ağlarını ve genetik algoritmaları daha temel ve deneysel bir bakış açısıyla anlamama yardımcı oldu. “yapay sinir ağı”, “uygunluk fonksiyonu”, “çaprazlama” ve “mutasyon” gibi kavramları gerçek bir oyun döngüsü içinde çalışır hale getirmem gerekti.
Ayrıca girdi tasarımının ne kadar önemli olduğunu öğrendim. Ajana 16 farklı yöndeki mesafe bilgisini vermek, ortamı tanımlamak için basit bir yöntemdi ancak ajanın anlayabileceği bilgileri de sınırlandırıyordu. Sistemin davranışı yalnızca kullanılan algoritmaya değil, oyun durumunun nasıl temsil edildiğine de bağlıydı.
Son Düşünceler
Küçük ölçekli bir proje olmasına rağmen bu çalışma, yapay zeka sistemlerinin oyunlarla nasıl etkileşime girebileceğini öğrenmem açısından önemli bir adımdı. Oyun geliştirme, sinir ağı davranışı, genetik algoritmalar ve gerçek zamanlı görselleştirmeyi tek bir deneyde bir araya getirdi.
Ortaya çıkan sonuç tamamen optimize edilmiş ve Asteroids oyununda uzmanlaşmış bir yapay zeka değildi. Buna rağmen bir ortam oluşturma, ajan girdilerini ve çıktılarını tasarlama, davranışları puanlama, ağları evrimleştirme ve sonuçları gözlemleme süreçlerinin tamamını anlamamı sağladı.