26 Eylül 2017 Salı

Yapay Zeka Oyunları - 4


Parça parça yayınlamakta olduğum Yapay Zeka Oyunları 'nın 4. Makalesi ve örnek kodları sizlerle paylaşıyorum. Yapay zeka, yapay zeka oyun ve yapay zeka kodları ile ilgili makalelerini uzun olmaları nedeniyle sizlerle parça parça paylaşıyorum.

Yapay Zeka Oyunları Sonlu Durum Makineleri

Sonlu durum makineleri, aynı zamanda yapay zekayı programlamanın en etkili ve en sık kullanılan yöntemlerinden biri olan en az karmaşık olanlardan biridir. Bir bilgisayar oyunundaki her nesne için, ömrü boyunca bulunduğu bir dizi durumu ayırt etmek mümkündür. Örneğin: Bir şövalye kendisini silahlandırıyor, devriye geziyor, saldırıyor veya savaştan sonra dinleniyor olabilir. Bir köylü tahta topluyor, bir ev inşa ediyor ya da saldırılara karşı kendisini savunuyor olabilir. Durumlarına bağlı olarak, oyun içi nesneler, harici uyaranlara (sonlu küme) farklı şekillerde tepki verirler veya farklı faaliyetler gerçekleştirirler. Sonlu durum makinesi yöntemi, her oyun nesnesinin davranışının uygulanmasını kolayca ayıklamak ve genişletmek için daha küçük parçalara bölebilmemizi sağlar. Her devletin, nesnenin o devrede başlatılması ve deinitialization (durum geçiş kodu veya başlatma kodu olarak da bilinir), oyunun her çerçevesinde yürütülen koddan (Örnek: Yapay zeka işlevlerinin ihtiyaçlarını karşılamak veya uygun bir animasyon çerçevesi) ve çevreden gelen iletileri işlemek ve yorumlamak için kodlanır.

Sonlu durum makineleri genellikle aşağıdaki iki yöntemden birini kullanır:

1- Sonlu durum makinesi dili - C'de önişlemci makroları seti olarak uygulanır.
2- Devlet tasarım deseni - Nesne yönelimli özel bir proje modeli kullanılır.

Nesne yönelimli tasarım ve programlama çağında, birinci yöntem, yani bir proje kalıbı durumuna dayalı olarak uygulanan makineler tarafından aşamalı olarak bırakılıyor. Aşağıda, bir şövalyenin kısmen olası davranışını açıklayan böyle bir nesne yönelimli makineye bir örnek verilmiştir; Nesnenin her durumu bir soyut temel sınıfla temsil edilir:

Nesneye yönelik tasarım ve programlama çağında, birinci yöntem, bir proje model durumuna dayanarak uygulanır. İkinci yöntem yani AI tarafından dışlanma durumudur. Aşağıda, bir şövalyenin kısmen olası davranışını açıklayan ve bir nesne yönelimli AI’ye bir örnek verilmiştir. Nesnenin her durumu bir soyut temel sınıfla temsil edilir.

class CGameObjectState{
public:
   virtual void OnEnter()                 { return; }
   virtual void OnLeave()                 { return; }
   virtual void OnUpdate()                { return; }
   virtual void OnMessage(CMsg* pMessage) { return; }
};

Bu class’ta türetilen tüm classlar, oyundaki davranışı tanımlar. (Listeleme 2, 3 ve 4 bakınız). Oyun içi bir nesnenin mevcut durumunun temel classın nesnesine bir işaretçi ve durum geçişini destekleyen bir yöntem içerir (Liste 5’e bakınız). Bir şövalye classı, ana nesneden türetilir ve AI varsayılan durumu başlatır.

class CKnightObject : public CGameObject{
   CKnightObject(){
      SetState(new CKnightPatrolState());
   }
};
Liste 2. Saldırı Altındaki Şövalye

class CKnightAttackState : public CGameObjectState{
   void OnUpdate(){
      // If no enemy seen, change to "patrol" state
      if(CanSeeEnemy()==FALSE)
         SetState(new CKnightPatrolState());
      // Here is the code handling the attack, e.g. get as close as needed
      // to the target if it is too far away, use the sword if it is close
      if(IsEnemyCloseEnough()==FALSE)
         MoveToEnemy(enemyID);
      else
         HitTheEnemy(enemyID);
   }
   void OnEnter(){
      // Alert allied troops that you're under attack
      CallForReinforcement();
   }
   void OnLeave(){
      // Notify command of received wounds
      CallForMedic();
   }
   void OnMessage(CMsg* pMsg){
      // Check the type of the order, take appropriate action if it is
      // a "fall back" order
      CMsgGetBack* pGetBackMsg = dynamic_cast<CMsgGetBack*>pMsg;
      if(pGetBackMsg != NULL)
         SetState(new CKnightRunAwayState());
   }
};
Liste 3. Devriye Şövalyesi

class CKnightPatrolState : public CGameObjectState {
   void OnUpdate(){
      // Here is the code to check if we can see the enemy
      if(CanSeeEnemy() == TRUE){
         SetState(new CKnightAttackState());
      }
      else{
         // Continue the march through subsequent way points of the patrol
         GoToNextPatrolPoint();
      }
   }
   void OnLeave(){
      // Notify we are not patrolling any more, a substitution may be needed
      NotifyOneLessInPatrol();
   }
};
Liste 4. Düşmandan Kaçan Şövalye

class CKnightRunAwayState : public CGameObjectState{
   void OnUpdate(){
      // Here is the code to check if we can see the enemy
      if(CanSeeEnemy() == FALSE){
         SetState(CKnightPatrolState());
      }
      // Run as far away as possible from the nearest enemy
      RunFarAwayFromNearestEnemy();
   }
};
Liste 5. Nesnenin hal ve durum geçişini sunma

class CGameObject{
   CGameObjectState* m_pMyState;
public:
   SetState(CGameObjectState* pNewState){
      // Call the deinitialisation method and destroy the object
      m_pMyState->OnLeave();
      delete m_pMyState;
      // Assign the new state to the object
      // and call the method initialising it
      m_pMyState = pNewState;
      m_pMyState->OnEnter();
   }
   OnUpdate(){
      // perform tasks as defined for the present state
      m_pMyState->OnUpdate();
      // now perform other, per-frame tasks of the object
   }
   void OnMessage(CMsg* pMsg){
      // perform tasks as defined for the present state
      m_pMyState->OnMessage(pMsg);
      // now process the messages, regardless of the object's state
   }
};

Yapay Zeka ve Yapay Zeka Oyunları ile ilgili ilerleyen zamanlarda daha ayrıntılı yazılarımızı sizlerle paylaşmaya devam edeceğim. 


Daha önceki Yapay Zeka Oyunları - 3. bölümü için tıklayın.

Hiç yorum yok:

Yorum Gönder