游戏开发中的人工智能(九):有限状态机

版权声明:本文为Jurbo原创文章,转载请加上链接和作者名,标明出处。 https://blog.csdn.net/Jurbo/article/details/75899108

接上文 游戏开发中的人工智能(八):描述式 AI 及描述引擎

本文内容:有限状态机是游戏软件 AI 的基本要素。本章探讨有限状态机的基础,以及如何予以实现。


有限状态机

有限状态机是一种抽象机制,是处在各种不同的预定状态下的其中一种状态。有限状态机也可以定义一组条件,以确认何时应该改变状态。实际的状态会决定状态机的行为。

本章我们要讨论有限状态机的基础,教你如何实现它。

状态机的基本模型

有限状态机模型,如图9-1 所示。

这里写图片描述

如图9-1 所示,在有限状态机中,每个可能的状态都以圆圈表示。此图中有四种可能的状态:Si,S1,S2,S3**。每个有限状态机中,都需要采用一种方法使其从一种状态转换到另一种状态。就此图而言,转换函数以 t1、t2、t3、t4、t5 来表示。一开始初始状态是 Si,一直到 t1 转换函数提供刺激值时才会改变其状态。一旦提供了刺激值,状态就转换成 S1。即:从一种状态转换成另一种状态,要看是由哪个转换函数提供的刺激值。**

下面举一个“Pac-Man(小精灵)”游戏里的魔鬼的例子,鬼怪有限状态机如图9-2 所示:

这里写图片描述

图9-2 中,每个方块代表游戏 AI (即鬼怪)的可能的状态。就此例而言,有三种可能状态:游走(roam)、闪躲(evade)、追逐(chase)。箭头表示可能存在的转换,同时也显示出哪些条件下这几种状态可以改变或维持不变。

就此而言。鬼怪最初的状态是“游走”。有两个条件可以引发状态改变。第一个条件是“blue true 鬼怪变成蓝色”。当玩家吃了大力丸后,鬼怪就会变成蓝色,然后鬼怪就会从状态“游走”转换为“闪躲”。另一个可以改变状态的条件是“see true 看见玩家”,即当鬼怪看见玩家时,就会从状态“游走”转换成“追逐”。

此图还显示,当鬼怪是蓝色时,会持续保持“闪躲”状态。除此之外,如果看得见玩家,则状态会从“闪躲”转为“追逐”。如果在“追逐”中看不见玩家,则会转换到“游走状态”。

例9-1 是针对图9-2 的程序代码:

//例9-1:鬼怪的行为

switch(currentState)
{
    case kRoam:
        if(imBlue==true)
            currentState=kEvade;
        else if(canSeePlayer==true)
            currentState=kChase;
        else if(canSeePlayer==false)
            currentState=kRoam;
        break;

    case kChase:
        if(imBlue==true)
            currentState=kEvade;
        else if(canSeePlayer==false)
            currentState=kRoam;
        else if(canSeePlayer==true)
            currentState=kChase;
        break;

    case kEvade:
        if(imBlue==true)
            currentState=kEvade;
        else if(canSeePlayer==true)
            currentState=kChase;
        else if(canSeePlayer==false)
            currentState=kRoam;
        break;
}

设计有限状态机

我们将设计有限状态机分为两步:

  1. 讨论存储与游戏软件 AI 实体相关的数据的几种结构类型
  2. 讨论如何建立函数转换状态机的状态

有限状态机的结构和类

例9-2 说明了典型的游戏中,怎样以一种单一类结构,存储游戏软件 AI 实体的数据。

//例9-2:游戏软件 AI 结构

class AIEntity
{
    public:
        int type;
        int state;
        int row;
        int column;
        int health;
        int strength;
        int intelligence;
        int magic;
};

例9-3 定义状态常量:

//例9-3:状态常量

#define kRoam 1
#define kEvade 2
#define kAttack 3
#define kHide 4

有限状态机行为及转换函数

实现有限状态机的下一步是提供函数,以决定 AI 实体的行为以及何时应该改变状态。如例9-4 所示。

//例9-4:游戏软件AI 转换函数

class AIEntity
{
    public:
        int type;
        int state;
        int row;
        int column;
        int health;
        int strength;
        int intelligence;
        int magic;
        int armed;

        Boolean playerInRange();
        int checkHealth();
}

在 AIEntity 类中我们新增了两个函数。例9-5 说明了如何利用这两个转换函数,改变状态机的状态。

//例9-5:改变状态

if( (checkHealth() < kPoorHealth) && (playerInRange()==false) ) 
    state=kHide;
else if(checkHealth()<kPoorHealth)
    state=kEvade;
else if(playerInRange())
    state=kAttack;
else 
    state=kRoam;

例9-5 中第一个 if语句用来检查 AI 实体的健康值是否太低,以及玩家是否不在附近。如果这些条件都成立,则由此类结构所表示的生物,将进入“隐藏”状态。第二个 if 语句用来检查健康值下限。如果我们运行到这个 if 语句,就表示玩家在附近。因为如果不在附近,第一个 if 语句的评估结果就会成立。因为玩家可能会看见该生物,所以我们要转换成“闪躲”状态。第三个 if 语句用来检测玩家是否在附近,此事的 AI 健康状态应该是良好的,否则前两个 if 语句中的其中一个就应该成立了。因为玩家在附近,且AI 健康状况良好,于是我们转换成“攻击”状态。否则,我们进入默认的“游走”状态。直到转换函数指定的条件指出该状态应该改变为止。

猜你喜欢

转载自blog.csdn.net/Jurbo/article/details/75899108