欢迎光临散文网 会员登陆 & 注册

基础 | 简单的智能体----有限状态机(六)

2020-03-08 14:38 作者:有木乘舟  | 我要投稿

本系列为笔者初学c/c++和游戏AI开发的学习经历,练习为主,不涉及到具体的游戏开发软件学习(如unity,虚幻4等),适合刚入门的小伙伴一起学习探讨,欢迎在评论区留下意见。

  •  开发语言:c/c++ (11及以上) 

  • 开发平台:macOS mojave / Linux 

  • 编译器:vs Code / g++

三、代码实现

3.3 矿工Bob

  在3.2里我们定义了一个居民类,表示小镇上的居民都具有的一些共同特征。之后,我们又将构建一个“矿工类”,这个类描述了“矿工”的属性、状态和行为,是一个真正意义上的智能体。

  Bob会渴,会饿,会走来走去,会睡觉,会挖矿。这些都是有别于其他居民的特征和行为,也是他作为一个游戏智能体的存在条件。虽然比较简单。

  这里,我们需要用到c++的特性之一,继承

  类继承能够从已有的类派生出新的类,而派生类继承了原有类(称为基类)的特征,包括方法。

----《C++ Primer Plus

  继承的目的之一,就是为了提高代码的重用性。这样,不管我们创建多少个“矿工Bob”,都可以只用同一套代码来表示他们的共性。而不用每个人都写一遍。

3.3.1 Miner类实现

图10 Miner类

  可见,Miner类公开继承了BaseGameEntity类,也就是说每个Miner类都会有一个ID和Update()函数,由于Update()函数是纯虚函数,因此它不用在基类中实现,但是一定要在派生类中被覆盖且实现。

  方框里是Miner类的一些行为函数,当Bob处在某个状态中时,他的一些属性会发生变化,这些改变通过方框里的函数来实现。 

  其中某些函数用到了关键字const用来定义一个不会被改变的常量,可修饰 普通变量、指针、函数参数和类的成员函数。

  •   const 修饰类成员函数,其目的是防止成员函数修改被调用对象的值。

图11 Miner类初始化

  图11是Miner类的初始化,除了必须有的id之外,注意我们一开始也是要给Miner类一个初始状态GoHomeAndSleepTilRestted::Instance() ,这个类就是接下来要讲的具体状态类。

  目前,一个矿工只有四种状态,也即一个Miner类有四个具体状态类。

  其中,我们重点了解一下Update()和ChangeState()的实现:

  • Update()函数被用来更新Bob的状态,每个时刻执行一次,每次执行的时候饥渴值+1,同时执行当前状态的Excute()函数。之所以这样做,是因为我们用状态模式将具体状态类从Miner类中分离了出去,并用单例模式来实现,因此Miner类只能通过Update()来更新状态。

图12 Update()


  • ChangeState()函数被用来改变Bob的状态,只有当满足某种条件之后才会执行。我们规定每次改变状态的时候,都要先用Exit()来退出当前的状态,再通过Enter()来进入新的状态。

图13 ChangeState()

  最后一点,我们额外定义了一个枚举类型来存储Bob的位置,方便记忆和操作:

图14 location_type枚举类型

知识点:

  • 类的实现 & 类的初始化方式

  • 继承

  • const关键字的用法

  • 枚举类型

参考: 

  • 《游戏人工智能编程案例精粹》

  • 《C++ Primer Plus》 

相关代码下载:https://github.com/linpeijie/GameToy/tree/master/GameAI/FSM

基础 | 简单的智能体----有限状态机(六)的评论 (共 条)

分享到微博请遵守国家法律