Sayfalar

11 Şubat 2010 Perşembe

Bir Garip Yapay Zeka..


Oyun projesi için çalışmalarımız çok düzenli olmasa da devam ediyor .Projeyi tamamlamak için bir çok değişik alanda araştırma ve denemelerin yapılması gerekiyor . Zamana yayıp aklımızdaki yeni fikirleri de ekleyip tamamlayabilmek ilk hedefimiz .Şu anda kullanıcımız kendi tankımı yönetip ateş edebiliyor ama bu yeterli değil tabiki bilgisayarın düşman tankları yönetebilmesi gerekiyor .

Yapay zeka dersinde gördüğümüz algoritmalar daha çok en kısa yolu bulma ile ilgili algoritmalar .Bu algoritmalar bu oyunda pekte işe yaramıyor aslında .Düşmanın En kısa yolu bulup direkt olarak hedefe yönelmesi onu fazlaca akıllı yapacaktır .Bu bizim pek işimize gelmeyecekti . Bizim işimize daha çok rasgele hareket eden ve engellere göre yönünü değiştiren bunlara ek olarak hedefe yönelik hareketler de gösterebilen davranışlar yarayacaktı .

public void otonom_tank()
{
hareket_sayisi = (hareket_sayisi + 1) % degisim;
if (hareket_sayisi%30 == 0)
{
tank_yon_degis();
}
if (hareket_sayisi != 0)
{
if (engel_var_mi(tank_yon))
{
tank_hareket_et(tank_yon);
}
else
{
tank_hareket_et(random.Next(0, 4));
}
}
else if(hareket_sayisi==0)
{
degisim = random.Next(30, 70);
yonelme(yonel);
}
}

Yukarıda bulunan kod bloğu düşman tanklarının hareketlerini sağlayan metodumuz . Bu metodumuz tankın her bir hareketini hareket_sayısı değişkeninde tutuyor . Bu değişkenin modunu belli bir sayıya göre aldığımızda ve sıfıra eşitlendiğinde raslantısal hareket eklenir .
Kırmızı renkteki blok tankların engelle karşılaştığı zaman yönünü değiştirmesini sağlıyor.
En son kısmında ise yonel değişkeninde tutulan kordinata doğru bir yönelme gerçekleştiriyor .
Bu yönelme bizim savunmasını yapacağımız yerin kordinatını tutacak . Rastgele hareketlerle tanklar bizim savunmasını yapacağımız yere ateş etmesi düşük bir olasılık olduğu için yönelme davranışını ekledim.
public void yonelme(Point koor)
{
int rand=random.Next(0,2);
if (rand == 0)
{
if (koor.Y > tank_koor.Y)
{
tank_hareket_et((int)yonler.asagi);
}
else
{
tank_hareket_et((int)yonler.yukari);
}
}
else
{
if (koor.X > tank_koor.X)
{
tank_hareket_et((int)yonler.sag);
}
else
{
tank_hareket_et((int)yonler.sol);
}
}
}


Yönelme fonksiyonun mantığı basit hedef kordinatın x veya y değerlerine bakarak yönünü belirliyor .Eğer x koordinatı tankın kordinatından büyükse tankın yönünü ona çeviriyoruz. Y değeri içinde aynısını yapıyoruz .
İşin kötü tarafı tankların rastgele hareketlerinde biraz sorun yaşıyorum .Resimde gördüğümüz tanklar ilk başta tamamen dolu bir alanda başlamışlardı ve ateş ederek resimdeki gibi duvarları yıktılar .Sağ taraftaki iki tankın aynı yerler gidip ateş ettiğini anlıyoruz . Her ne kadar global random değerler kullanmış olsam da şimdilik bu sorunu çözemedim.

Tankların bu hareketlerine ek olarak ateş etmesi de biraz akıllı hale getirebiliriz .Mesela önünde engel varsa ateş et ,düşman varsa ateş et gibi .