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

本系列为笔者初学c/c++和游戏AI开发的学习经历,练习为主,不涉及到具体的游戏开发软件学习(如unity,虚幻4等),适合刚入门的小伙伴一起学习探讨,欢迎在评论区留下意见。
开发语言:c/c++ (11及以上)
开发平台:macOS mojave / Linux
编译器:vs Code / g++

二、项目的设计模式
2.1 状态模式
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
----《设计模式》 GoF
书中的例子运用了“状态模式”来设计项目的整体结构,该模式天然契合有限状态机这类模型,因为有限状态机本来就是以一系列的状态和一系列的动作来建模一个智能体,且这些状态是相对独立的。
简单的理解,就是当Bob处在挖矿这个状态当中,每个时刻都会更新一下当前状态,而更新这个行为,包含了许多动作,这些动作可以导致状态的变化。
“状态模式”保证了从设计层面上,可以更加合理的实现有限状态机模型。
2.1.1 基础结构
一个状态模式通常包含三个大类:
Context类(上下文类):上下文类的状态存在多样性,并且在不同的状态下,对象表现出不同的行为。在上下文类中,维护了一个抽象状态类的实例。
State类(抽象状态类):声明了一个接口,用于封装与在上下文类中的一个特定状态相关的行为,在子类中实现在各种不同状态对应的方法。
ConcreteState类(具体状态类):实现具体状态下的方法,每一个具体状态类对应一个具体的状态。

2.1.1 Bob的结构
对应到“Bob的一天”这个项目中,我们也可以画出这样的一个UML图来:

从上图我们可以很清晰的看出:
蓝色部分为Context类,其中:
BaseGameEntity类是小镇中所有人物的基类,定义了一个人具有的普遍特性
Miner类继承BaseGameENtity类,是State类的实例化对象
Miner类其实例化后的对象就是Bob这个人物
绿色部分为State类,是封装了任何状态变换的逻辑的接口,每个状态类都会调用到State类里面定义的函数。
红色部分为ConcreteState类,是具体的状态类,包含实现细节,如挖矿状态类包含三个动作:走到矿场;挖金矿;离开矿场。
2.1.1 状态模式的优缺点
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。
把状态的判断逻辑转移到表示不同状态的一系列状态类当中,可以把复杂的判断逻辑简化。
通过模块化的分隔一个对象的状态和行为,定义新的子类可以很容易地增加新的状态和转换。
避免出现大量的 if-this-then-that 条件分支语句,简化代码。

这样,运用状态设计模式后,我们就可以将之前设计的逻辑流程图转化为计算机可识别、可实现的架构,为下一步的代码实现打下坚实的基础。
设计模式,是前辈们在实践中总结出来的经验结果,能够灵活运用设计模式可以避免开发中的很多问题。但是设计模式也需要结合实际情况来灵活使用,不应过度设计。

参考:
《游戏人工智能编程案例精粹》
《设计模式》 GoF
相关代码下载:https://github.com/linpeijie/GameToy/tree/master/GameAI/FSM