游戏编程中的人工智能技术-演化算法入门

   buckland大神的每一章都很经典,少了任何一章都会感到不完整。今天先介绍第十章-演化算法。因为这是人工生命的基础。大名鼎鼎的tierra就是采用了演化算法。(什么是Tierra?看这里点击打开链接)

    演化算法的思路就是让弱小的生命体“死亡”,再让强大的生命体代替“死亡”的生命体,从而保证种群的一直延续,并且,生命体基于求生的本能,避免被“死亡”,会衍生出各种叹为观止的新行为,称之为生物的多样性。因此,演化算法的思路可以概括为:如何筛选弱小的生命体进行“死亡”操作(Tierra里称之为“死神”、“收割机”),以及如何用强大的生命体进行替代。

    若想让生命体“死亡”,除了创建一个std::vector作为种群外,还必须创建另一个向量std::multiset,称之为“池”。“池”中的生命体不是显示在游戏屏幕上的,而是在后台运作的一个“母体”,因为游戏画面上所有的生命体都是从“池”中孵化得来的,弱小的即将被杀死的生命体也会丢弃到这个池中等待“死神”“收割”。替代死亡生命体也是从“池”中选出的最强壮的生命体。因此,“池”必须具备两个特征:

    (1)“池”中生命体的数量必定比游戏画面上“种群”中生命体的数量要大的多。

    (2)“池”必须是有序向量,这样才能简便的分辩谁是弱小生命体,谁是强壮生命体。

    ok,闲话不多说,直接进入代码。本节中只介绍关于演化的那一部分,其他部分,例如外星人部分,神经网络部分等不在介绍。

    先看相关参数设定。

class CController 
{
private:

  //the player's gun
  CGun*            m_pGunTurret;

  //the pool of aliens
  multiset m_setAliens; //设定“基因组池”,使用multiset容器,利用二叉树实现,详细内容参见教材P235页

  //the currently active aliens
  vector   m_vecActiveAliens;//这个是显示在游戏画面上的种群

  int              m_iAliensCreatedSoFar;
 
  int              m_iNumSpawnedFromTheMultiset;

  //vertex buffer for the stars
  vector   m_vecStarVB;

  //keeps track of the window size
  int              m_cxClient,
                   m_cyClient;

  //lets the program run as fast as possible
  bool             m_bFastRender;
 
  //custom pens used for drawing the game objects
  HPEN             m_GreenPen;
  HPEN             m_RedPen;
  HPEN             m_GunPen;
  HPEN             m_BarPen;


  void    WorldTransform(vector &pad);
    
  CAlien  TournamentSelection();


public:
  
  CController(int cxClient, int cyClient);

  ~CController();

  //The workhorse of the program. Updates all the game objects and
  //spawns new aliens into the population.
  bool  Update();//演化计算在这里

  void  Render(HDC &surface);

  //resets all the controller variables and creates a new starting
  //population of aliens, ready for another run
  void  Reset();

  //-----------------------------accessor functions
  bool FastRender(){return m_bFastRender;} 
};
接下来介绍演化计算相关的Update程序。

//------------------------------- Update ---------------------------------
//
//  The workhorse of the program. Updates all the game objects and
//  spawns new aliens into the population.
//------------------------------------------------------------------------
bool CController::Update()
{
  
  //switch the autogun off if enough offspring have been
  //spawned
  if (m_iNumSpawnedFromTheMultiset > CParams::iPreSpawns)
  {
    m_pGunTurret->AutoGunOff();

    m_bFastRender = false;
  }
  
  //get update from player for the turret movement
  //and update any bullets that may have been fired
  m_pGunTurret->Update();
    
  //move the stars
  for (int str=0; strm_vecBullets,
                               m_pGunTurret->m_vPos))//如果外星人“死”了
    { 

      //first we need to re-insert into the breeding population so
      //that its fitness score and genes are recorded.
      m_setAliens.insert(m_vecActiveAliens[i]);//将死去的外星人插入“池”中

      //if the required population size has been reached, delete the 
      //worst performer from the multiset
      if (m_setAliens.size() >= CParams::iPopSize)//如果池中的数目满了,iPopSize是池中生命体最大数量
      {      
        m_setAliens.erase(--m_setAliens.end()); //将池中最后的,也就是适应度最差的外星人删去,即“收割”操作       
      }

      ++m_iNumSpawnedFromTheMultiset;
                  
      //if early in the run then we are still trying out new aliens
      if (m_iAliensCreatedSoFar <= CParams::iPopSize)//如果刚开始,池中的生命体还没满的话,就新建一个生命体,来替代死去的
      {
        m_vecActiveAliens[i] = CAlien();

        ++m_iAliensCreatedSoFar;          
      }

      //otherwise select from the multiset and apply mutation,如果池中生命体满了的话,就从池中进行精英选择,来替代死去的
      else
      {         
        m_vecActiveAliens[i] = TournamentSelection();

        m_vecActiveAliens[i].Reset();

        if (RandFloat() < 0.8)
        {
          m_vecActiveAliens[i].Mutate();
        }
      }
    }
  }//next alien

  return true;
}


你可能感兴趣的:(人工智能,遗传算法,神经网络)