AI逻辑实现-选择行为树还是状态机? 
关注AI的朋友可能会看过赖勇浩翻译的《有限状态机时代终结的10大理由》 ,里面谈到了状态机的诸多弊端。同时在ppt(附上下载地址)中述说了行为树的诸多优点,这里就不在赘述了。更多得是想总结一下自己玩了一阵子行为树后的一些实践体会。

个人体会: 
状态机来实现AI更符合我们思维的朴素表达,我想任何一个有经验的coder都能直观得去写一个自己的AI状态机。它用于一些简单的ai其实是没有大问题的,(搜索敌人,靠近,攻击,死亡)用状态机其实更加便捷。但是面对一些复杂的ai逻辑实现就会显得比较繁杂。同时,当需要对现有行为逻辑进行扩展的时候,代码上就会显得比较吃力,因为要维护的状态量会成倍增加。 
 
行为树,实现AI的过程更加得有技巧,框架设计者较为全面考虑了我们可能会遇到的种种情况,把每种情况都抽象成了一个类型的节点,而我们要做的就是按照规范去写节点,然后把节点连接成一颗行为树。更加得具有面向对象的味道,行为模块间的藕合度相对较低。

举个粗糙的例子来比较一下两者的不同: 
AI行为:吃饭 睡觉 打豆豆(很消耗体力和脑力的;)

1.打豆豆 HP -= 5 / 秒 MP -= 3 / 秒 
2.吃饭 HP += 10/秒 MP -= 1 / 秒 
3.睡觉 MP += 15/秒 HP -= 2/秒 
4.吃饭和睡觉是不可打断的动作(pending),必须执行到吃饱(HP = 100) or 睡饱(MP = 100) 
5.打豆豆是瞬发动作,每帧都可以执行一次

状态机的实现逻辑图: 
 
行为树的实现逻辑图: 
 
其实不管你知不知道什么是selector,condition都不要紧,至少从上图,应该可以看出来,行为树节点间的联系并不像状态机那样得“紧密”。

选择两种不同的ai实现方法,也决定了具体行为的实现逻辑。 
比如对于sleep动作的实现,如果是状态机: 
function sleep() = 
if Y == 100 then 
AwakeEvent() 
return 
end 
HP -= X 
MP += Y 
end 
然后每一帧执行sleep()

如果是选择行为树: 
function sleep() 
local sleepTime = (100/15) 
–不好意思乱入了一段cocos2dx的代码 
self:runAction(cc.Sequence:create(cc.DelayTime:create(sleepTime),cc.CallFunc:create(cancelPending))) 
local cancelPending = function() 
pending = false 
end 
end

罗列一下行为树的概念: 
对于有限状态机而言,必须明确 状态的转换方式;对于行为树,必须明确状态前提:前提条件 
每一个行为必须有“前提条件” ,这决定了该行为是否被选择。 
行为树的运算也是通过帧循环的update来驱动,不一定是每帧都update,但是要周期性update。 
每一次run从根节点(root)开始,每一运行都会选择一个可行的子节点运行,这种选择可以是随机方式,也可以是预设好优先条件 
行为树由叶子节点和中间节点组成,叶子节点是最基本的行为(如跑动,攻击),中间节点代表逻辑单元(巡逻,逃跑)。 
当一个叶子节点被选择后,就会激活其对应的基本的行为 
最基本的行为可能执行成功也可能失败。 
高等级的行为(中间节点)是否执行成功依赖于他们的孩子节点是否执行成功。 
一个子节点失败可能导致父母节点选择另外一个孩子。 
除了选择(selector)一个单独的子节点行为,一个节点还可能顺序(sequence)or并行(concurrent)得运行他的所有子节点。 
一个行为除了有前提条件,可能还有上下文条件(父节点or孩子节点可能存储一定的状态变量)。 
高优先级的行为可能抢占低优先级的行为

转载一段akara的行为树实现方案:

  • Composite Node 组合节点
  • Decorator Node 装饰节点
  • Condition Node 条件节点
  • Action Node 行为节点

各种节点的详细描述: 
* Selector Node 选择节点 
描述:从头到尾,按顺序选择第一个执行条件为真的子节点,遇到True停止。 
处理流程:当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:如遇到一个Child Node执行后返回True,那停止迭代,本Node向自己的Parent Node也返回True;否则所有Child Node都返回False,那本Node向自己的Parent Node返回False。

  • Sequence Node 序列节点 
    描述:从头到尾,按顺序执行每一个子节点,遇到False停止。 
    处理流程:当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:如遇到一个Child Node执行后返回False,那停止迭代,本Node向自己的Parent Node也返回False;否则所有Child Node都返回True,那本Node向自己的Parent Node返回True。

  • Parallel Node 并行节点 
    描述:从头到尾,平行执行它的所有子节点。 
    Parallel Selector Node: 有一个子节点True返回True,否则返回False。 
    Parallel Sequence Node: 有一个子节点False返回False,否则返回True。 
    Parallel Fall On All Node: 所有子节点False才返回False,否则返回True。 
    Parallel Succeed On All Node: 所有子节点True才返回True,否则返回False。 
    Parallel Hybird Node: 指定数量的子节点返回True或False后,才决定结果。

  • Decorator Node 装饰节点 
    描述:装饰节点一般用来作为额外的附加条件。例如,时间间隔控制,次数控制,频率控制,结果取反,错误处理等。

  • Condition Node 条件节点 
    描述:顾名思义,就是对应条件的节点。

  • Action Node 行为节点 
    描述:顾名思义,就是用于完成某种动作的节点。

从代码实现的角度来谈下优缺点

优点: 
1. 行为逻辑和状态数据分离,任何节点写好以后可以反复利用 
2. 重用性高,可用通过重组不同的节点来实现不同的行为树 
3. 呈线性的方式扩展,易于扩展 
4. 可配置,把工作交给designer 
5. 能够胜任”AI” “掉宝”等等场景。

缺点: 
1. 每一帧都从root开始,有可能会访问到所以的节点,相对State Machine消耗更多的cpu 
2. 任何一个简单的操作都必须要使用节点

原文地址:http://blog.csdn.net/u011484013/article/details/52369313

AI逻辑实现-取舍行为树还是状态机的更多相关文章

  1. 做游戏长知识------基于行为树与状态机的游戏AI(一)

    孙广东 2014.6.30 AI. 我们的第一印象可能是机器人,如今主要说在游戏中的应用. 现代的计算机游戏中已经大量融入了AI元素,平时我们进行游戏时产生的交互都是由AI来完毕的.比方在RPG游戏中 ...

  2. Unity教程之-基于行为树与状态机的游戏AI

    AI.我们的第一印象可能是机器人,现在主要说在游戏中的应用.关于AI的相关文章我们在前面也提到过,详细请戳这现代的计算机游戏中已经大量融入了AI元素,平时我们进行游戏时产生的交互都是由AI来完成的.比 ...

  3. 行为树实现AI逻辑

    http://blog.csdn.net/kenkao/article/details/6099966 http://www.aisharing.com/archives/99 http://www. ...

  4. MMORPG大型游戏设计与开发(服务器 AI 逻辑设定和状态结点)

    人工智能(AI)中往往都会有这么一个问题,那就是我要做什么?我该怎么做?我需要什么?所以这里所谓的智能就是赋予AI对象的判断力,以及它根据判断得到的相应反应.就好比,你去商店买东西,钱够别人才卖给你, ...

  5. AI 逻辑回归

    逻辑回归 参考链接 https://zhuanlan.zhihu.com/p/44591359

  6. 【R语言学习笔记】 Day1 CART 逻辑回归、分类树以及随机森林的应用及对比

    1. 目的:根据人口普查数据来预测收入(预测每个个体年收入是否超过$50,000) 2. 数据来源:1994年美国人口普查数据,数据中共含31978个观测值,每个观测值代表一个个体 3. 变量介绍: ...

  7. 游戏AI之决策结构—有限状态机/行为树(2)

    目录 有限状态机 行为树 控制节点 条件节点 行为节点 装饰节点 总结 额外/细节/优化 游戏AI的决策部分是比较重要的部分,游戏程序的老前辈们留下了两种经过考验的用于AI决策的结构: 有限状态机 行 ...

  8. 人工智能AI------有限状态机、分层状态机、行为树

    https://www.cnblogs.com/zhanlang96/p/4793511.html 人工智能遵循着:感知->思考->行动决策方法:有限状态机(Finite-State Ma ...

  9. UE4蓝图AI角色制作(六)之行为树

    13.行为树原理 AI最重要的环节就是行为树.我们将解释什么是行为树.为何它如此重要,以及构建行为树需要哪些元素. 借助行为树,我们可以轻松控制并显示AI的决策制定过程.行为树是一种将AI在场景中的决 ...

随机推荐

  1. 如何对多个文件进行MODELSIM仿真? (由于是一个很大的项目,不可能把所有MODULE都放在一个文件里。 如何在ModelSim中对多个.V文件进行仿真?)

    可以将所有要编译的所有文件的名字做一个list.新建一个文本文档,重命名为vflist vflist内容例子如下(src为文件夹):src/base_addr_chk.vsrc/config_mux. ...

  2. 翻翻git之---效果鲜明的类ViewPager库 ConvenientBanner(对图片载入部分进行改动)

    转载请注明出处:王亟亟的大牛之路 昨天写了篇基础的View绘制的内容貌似观众老爷们不怎么喜欢.那再这里再安利下自己定义View时.用到Paint Canvas的一些温故.讲讲用路径绘画实现动画效果(基 ...

  3. Oracle 每五千条执行一次的sql语句

    今天碰到一个问题,更新历史数据时,由于数据库表数据量太大,单行更新速度很慢,要求每五千条执行一次提交进行更新.执行SQL如下: declare i_count int; i_large int; be ...

  4. 递增和递减进度条CCProgressTimer

    关于scheduleUpdate看这篇即可 http://www.benmutou.com/blog/archives/56 接下来是示例代码: CCSize size = CCDirector::s ...

  5. kafka传数据到Flink存储到mysql之Flink使用SQL语句聚合数据流(设置时间窗口,EventTime)

    网上没什么资料,就分享下:) 简单模式:kafka传数据到Flink存储到mysql 可以参考网站: 利用Flink stream从kafka中写数据到mysql maven依赖情况: <pro ...

  6. web 安全问题(一):CSRF 攻击

    什么是CSRF CSRF是怎么产生的 CSRF的攻击对象 CSRG的攻击手段 CSRF的防御措施 什么是CSRF 全称是(Cross Site Request Forgery)跨站请求伪造.也就是恶意 ...

  7. cocos2d-x Schedule详解

    原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或已从场景中移除时,调度器会停止. Coc ...

  8. 使用 FreeRTOS 时注意事项总结(基础篇教程完结)

    以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的初始化流程推荐的初始化流程如下,本教程配套的所有例子都是采用的这种形式,当然,不限制必须 ...

  9. C# 回调与 javascritp 回调 比较

    C#: using System; using System.Collections.Generic; using System.Text; namespace Delegate { //定义委托,它 ...

  10. HBase shell 命令。

    HBase shell 命令. 进入hbase shell console$HBASE_HOME/bin/hbase shell如果有kerberos认证,需要事先使用相应的keytab进行一下认证( ...