Yapay Zeka - 1

Yapay Zeka

Yapay zeka ile ilgili biraz fikir vermesi açısından bir kaç yazı. Bu yazıları genel bir yapayzeka kaynağı olarak değilde, yeni başlayanlar için biraz fikir verecek, ilham kaynağı olabilecek bir döküman olarak görmek en iyisi. İçinde hatalar falan da vardır kesin. Neyse, umarım bir işe yarar..

Yazı 1

Çok Basit Yapay Zeka: (YIQ: 0-30 ) (YIQ: Yapay IQ: ben uydurdum, bilimsel değeri yok :) )

Bu tip yapay zekalar, pacman, mario gibi oyunlarda bulunur. Genel olarak önceden belirlenmiş bir yol izlerler. Kodlaması basittir.

Örnek bir kod inceleyelim:

Önce, yolumuzu tutacak yapıyı yazmalıyız:

Vector3F tipi, 3 lük bir array, bu da oyunun geçtiği dünyada bir hedef ve başlangıç koordinatı belirtiyor.

Yol tipi de, "zekalandırmak" (nasıl oluyosa) istediğimiz elemanın rotasındaki düz bir yol parçasını tutuyor. Zaman da o rotadaki ilerleme süresi

Rota tipi de Yol lardan oluşan tüm rotayı tutuyor. Aktif yol, o an gidilen yol parçasının indexi, geçZaman da şu anki aktif yola girdiği zaman (milisaniye cinsinden)

typedef Vector3F float[ 3 ] ;

typedef struct _yol
{
    Vector3F bas ;
    Vector3F son ;
    float zaman ;
} Yol ;

typedef struct _rota
{
    int yolSay ;
    Yol * yollar ;
    int aktifYol ;
    float gecZaman ;
} Rota ;

Şimdi de bu rota üzerinde adamımızı oynatacak bir fonksiyon:

Adamımızın tipinin Dusman olduğunu varsayıyorum ve bunun yer diye bir Vektor3F elemanı olmalı.

struct Dusman
{
...
...
    Vektor3F yer ;
    Rota *rota ;
...
...
}

Şimdi adamımızı oynatacak kod geliyor. Kod, önce geçen zamana göre Rota içinden seçilmesi gereken Yol u buluyor, sonra bu yoldaki koordinatını Lineer Interpolasyon (ismi gören korkar ama sadece ortalama almak gibi bişey) ile hesaplıyor.

void dusmanOynat( Dusman *dusman, float zaman )
{
    float *bas, *son ;
    // delta t: zaman farkı
    float dt ;
    
    // Eğer şimdiki yolun sonuna geliyorsak
    if( ( zaman ) > ( dusman->rota->gecZaman + dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ) )
    {
        // yola giriğ zamanını ayarla
        // bir önceki yola giriş zamanı ile yolun süresinin toplamı
        dusman->rota->gecZaman = dusman->rota->gecZaman + dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ;

        // bir sonraki yolu aktive et, sona geldiyse başa don..
        dusman->rota->aktifYol = ( dusman->rota->aktifYol + 1 ) % dusman->rota->yolSay ;
    }
    
    // şimdi yol içindeki konumu hesapla
    bas = ( dusman->rota->yollar[ dusman->rota->aktifYol ]->bas ) ;
    son = ( dusman->rota->yollar[ dusman->rota->aktifYol ]->son ) ;
    
    // delta t: şimdiki zaman eksi yola giriş zamanı
    dt = zaman - dusman->rota->gecZaman ;
    dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ;
    
    // burda da, şimdiye kadar geçen zamanı, yolda toplam harcanması gereken zamana bölüp,
    // yolun kaçta kaçını gitmesi gerektiğini bulduk.. onu da basit bi şekilde toplayıp, yeni yeri bulduk...
    dusman->yer[ 0 ] = bas[ 0 ] + ( son[ 0 ] - bas[ 0 ] ) * ( dt / dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ) ;
    dusman->yer[ 1 ] = bas[ 1 ] + ( son[ 1 ] - bas[ 1 ] ) * ( dt / dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ) ;
    dusman->yer[ 2 ] = bas[ 2 ] + ( son[ 2 ] - bas[ 2 ] ) * ( dt / dusman->rota->yollar[ dusman->rota->aktifYol ].zaman ) ;
}

Şimdi de bu fonksiyonu kodun içinden çağıracak bişeyler yazmak lazım..

Bir yerlerde, bizim bir pencere açan şunu bunu yapan bir kodumuzun olduğunuz varsayarak (bakınız NeHeGL base code) bu kodumuzdaki "Update( float milliseconds )" fonksiyonumuzun içine yazılacak kısmı yazmaya geçebiliriz:


// Bunlara biyerlerde değerler atanmalı
int dusmanlarinSayisi ;
Dusman *tumDusmanlar ;

void Update( float milliseconds )
{
    int i ;
    static float toplamZaman = 0 ;
    
    toplamZaman += milliseconds ;
    
    
    ...
    ..
    
    for( i = 0; i < dusmanlarinSayisi; i++ )
    {
        dusmanOynat( tumDusmanlar[ i ], toplamZaman ) ;
    }
    ....
    ...
}

Şunlara dikkat edilmesi gerekiyor:
  • Tüm düşmanlar için dizimiz doldurulmuş olmalı, yoksa hatalar verir..
  • Eğer sonuncu yol ilkine birleşmiyorsa, yolun sonuna geldiğinde atlama yapar. Birleşmesi daha iyi olur.
  • Kodu çalıştırıp test etmedim, belki yazım hataları olabilir.
Ziyaretci :: 2004 :: OyunYapimi.Org




Bu haberin geldigi yer: oyunyapimi.org
http://www.oyunyapimi.org

Bu haber icin adres:
http://www.oyunyapimi.org/modules.php?name=Sections&op=viewarticle&artid=58