一、什么是AI?
相信大家都很熟悉,AI,即 Artificial Intelligence 人工智能。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。
人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。
二、AI实现意义
AI 在游戏应用中的目的主要有:
- 新手过渡局,让玩家刚进入到游戏时,和较弱电脑对战,培养成就感,避免尚未熟悉游戏导致的挫折流失。
- 人机对战,给玩家练习新英雄或者挑战高难度电脑的机会。
- 温暖局,对连败玩家,匹配机器人去补偿一场胜利,舒缓连败挫折。
- 掉线托管,用强度合理的AI来补位掉线玩家,减少其他在线玩家的掉线局有损体验。
AI 的设计原则是:优秀的AI并不要求是尽量的和人表现一致,也不是多么的精准和无懈可击,而是能够和玩家进行很好的交互,提升游戏体验。
三、简单AI —— IF..ELSE..
AI越“智能”,策略就会越多,逻辑复杂度就越高。
而 IF..ELSE.. 只适合 逻辑复杂度简单,有规律行为 的AI 实现。
四、常用AI设计模式介绍
(一)FSM (Finite state machine) 有限状态机
概述:
一个有限状态机是一个设备,或是一个模型,具有有限数量的状态(State)。它可以在任何给定时间根据输入进行操作,使得系统从一个状态转换到另一个状态,或者是使一个输出或者一种行为的发生,一个有限状态机在任何瞬间只能处于一种状态。
示例,有限状态机的模型图
设计:
我们从一个经典例子来深入了解一下FSM:
设计一个简单的AI士兵甲,他具有以下特性:
- 他具有真实视野,发现敌人则进攻。
- 进攻时会瞄准敌人并射击,同时跑向敌人。
- 离初始位置过远,有可能是被调虎离山了,这时要回到初始位置。
- 进攻时离敌人过远,代表敌人逃跑成功,也要回到初始位置。
Add:
5. 被远距离武器瞄准,会跑向掩体,躲避攻击。
6. 到达掩体后,待机一段时间后,需要回到初始位置。
※ 总结:状态机是把时间片独立的事情抽象成状态,通过事件之间的转换把所有状态连接成一个状态机。
应用:
有限状态机应用非常广泛,且代码框架也非常简单。总结下来,代码框架可以分为以下三大部分:
优缺点:
优点:
- 逻辑复杂度不高、状态数量不多的时候,代码较为清晰,符合人类思维逻辑。
- 自由度高,可以在不同状态之间进行跳转。
缺点:
- 当状态机的模型复杂到一定的程度之后,也会带来实现和维护上的困难。
(二)HFSM(Hiearchical Finite state machine)分层有限状态机
概述:
FSM当状态太多的时候,不好维护,于是将状态分类,抽离出来,将同类型的状态做为一个状态机,然后再做一个大的状态机,来维护这些子状态机。
示例:
如图可见,这里有 车辆、撤退、自卫、交战、战后处理、闲置 六种大状态(state),每个大状态分别有各自的子状态。如:使用手雷、掩蔽、防御归为自卫,向尸体射击 和 搜查尸体 归为战后处理。
这样就组成了一个大的分层有限状态机。每个大状态下的子状态互不影响,相互隔离。降低了代码耦合性,可维护性增强。
优缺点:
优点:
- 从某种程度上规范了状态机的状态转移,而且状态内的子状态不需要关心外部状态的跳转,这样也做到了无关状态间的隔离。
缺点:
- 没有彻底解决FSM同样存在的问题——当状态机的模型复杂到一定的程度之后,还是会带来实现和维护上的困难。
(三)Behavior tree 行为树
概述:
以模块化方式描述了一组有限任务之间的切换。
行为树与分层状态机有一些相似之处,主要区别在于行为的主要组成部分是任务(Task)而不是状态(State)。行为树是无状态的。
整个算法先从树的根部开始(自顶向下),通过一些条件来搜索这颗树,最终确定需要做的行为(叶节点),并且执行它。
节点类型和状态:
两大节点类型:组合节点(Composite Node) 和 执行节点(Execution Node)、执行节点也可以叫 叶节点
三种节点状态:
- Running
- Success
- Failure
序列节点 Sequence Node:
按顺序执行子节点,直到一个子节点返回失败或所有子节点都返回成功。
与代码“&&”类似
选择节点 Selector Node:
按顺序执行子节点,直到其中一个返回成功或所有子节点返回失败。
与代码“||”类似
并行节点 Parallel Node:
将“并行”执行其所有子节点。之所以要加在并行上加引号,因为它不是真正的并行性;
在每次Tick时,每个子节点将按顺序单独Tick。无论子节点返回“成功”或“失败”都会继续运行
后续节点,保证所有子节点都得到运行后在根据每个子节点的返回值来确定最终的返回结果。
装饰器节点 Decorator Node:
它的功能正如它的字面意思:它将它的Child Node执行后返回的结果值做额外处理后,再返回给它的Parent Node。
最常见的应用就是“取非” , 即代码中的 “!”
示例:
回忆上述经典示例:
设计一个简单的AI士兵甲,他具有以下特性:
- 他具有真实视野,发现敌人则进攻。
- 进攻时会瞄准敌人并射击,同时跑向敌人。
- 离初始位置过远,有可能是被调虎离山了,这时要回到初始位置。
- 进攻时离敌人过远,代表敌人逃跑成功,也要回到初始位置。
- 被远距离武器瞄准,会跑向掩体,躲避攻击。
- 到达掩体后,待机一段时间后,需要回到初始位置。
用BT来表示:
乍眼一看好像也挺复杂的。。。
※ 但其实,这样自上而下的树结构会更便于理解和表达,模块耦合度也比较低。
优缺点:
不难看出,BT的优点:
- 易于理解并且可以使用可视化编辑器进行创建。
- 很大的灵活性,非常强大,并且非常容易对其进行更改。
- 能够创建由简单任务组成的非常复杂的任务,而不必担心简单任务是如何实现的。
- 每个行为逻辑互不影响,行为模块间的耦合度相对较低。
缺点:
- 行为树做的选择并不一定是最优的,结果也不一定是我们想要的。而且决策每次都要从根部往下判断选择行为节点,比状态机要耗费时间。每次决策都要经过大量的条件判断语句,会变得非常慢。
- 如果AI对象就只有3个或以下数量的状态,用行为树设计的话,计算量会更大,反而会更耗费性能。