当前位置: 首页 > news >正文

游戏算法-游戏AI行为树,python实现

参考文章:Behavior trees for AI: How they work (gamedeveloper.com)

本文主要参考上述wei'zProject Zomboid 的开发者 Chris Simpson文章的概念,用伪代码实现代码例子

AI概述


    游戏AI是对游戏内所有非玩家控制角色的行为进行研究和设计,使得游戏内的单位能够感知周围环境,并做出相应的动作表现的技术。游戏AI作为游戏玩法的一大补充,在各种游戏中都有广泛的应用,比如可以和玩家交互聊天的NPC,按照特定规则寻路的怪物,与玩家进行战斗对抗的机器人等。

目前实现游戏AI的算法有

有限状态机

AI行为树

还有其他比较少用的规则式AI,甚至神经网络等
 

行为树AI基本概念

        游戏行为树(Behavior Trees, BT)是一种用于游戏AI的设计模式。它通过模拟行为树来描述AI的行为和决策过程,以实现更加智能和自然的游戏AI。

游戏行为树由多个节点组成,每个节点代表一个行为或决策。它们按照特定的方式连接在一起,形成一个树状结构。在行为树中,根节点是AI的起点,通过遍历子节点来决策AI的行为。

节点有以下三种状态:

成功 success

失败 failure

运行 running

行为树节点有三种主要原型

组合控制节点 -Composite:

一种将多个子节点组合在一起的节点,用于实现复杂的行为和决策逻辑

主要包括

次序节点-Sequences:并行执行多个子节点,直到所有子节点都返回True或者任意一个子节点返回False为止

选择节点-Selector:按照顺序执行子节点,当某个子节点返回success时,停止执行并返回success

修饰节点-Decorator:

一种特殊的节点,它不执行具体的行为或决策,而是修饰其它节点的行为或决策

主要包括:

逆变节点-Inverter:它可以将子节点的结果倒转,比如子节点返回了 Failure,则这个修饰节点会向上返回 Success,以此类推。

重复节点-Repeater:重复执行其子节点指定的次数或者一直重复执行,直到其子节点返success或者failure

叶节点-Leaf:

树的最末端——叶子,就是这些 AI 实际上去做事情的命令或者是做一些判断

主要包括

条件节点-Condition:判断条件是否满足,如果满足则返回success,否则返回failure

行为节点-Action:执行某个具体的动作或行为,例如移动、攻击、使用技能等

节点表示

次序节点 ->Walk to Door (Success) ->次序节点(Running) ->Open Door (Success)  ->次序节点(运行中) ->Walk through Door (Success) ->次序节点(Running) ->Close Door (Success) ->次序节点(Running) -> 向次序节点的父节点返回 Success。

例如,考虑上一节中提到的逆变器装饰器:

在功能上与前面的示例相同,这里我们展示了如何使用逆变器来否定任何测试,从而为您提供一个 NOT 门。这意味着你可以大幅减少测试角色或游戏世界条件所需的节点数量。

三、伪代码实现

节点基类:

# 行为树节点基类
class BaseNode(object):def __init__(self):self.status = None  # 节点的执行结果: 成功 success 失败 failure 运行 runningdef execute(self, who):# 执行pass

叶子节点:行为节点

# 叶子节点-行为节点:吃食物
class EatFoodNode(BaseNode):def __init__(self, target):super(EatFoodNode).__init__()self.target = target  # 食物目标def execute(self, who):# 吃食物# who.eat_foot(self.target)self.status = "success"
# 叶子节点-行为节点:打开门
class OpenDoorNode(BaseNode):def __init__(self, target):super(OpenDoorNode).__init__()self.target = target  # 打开目标def execute(self, who):# 执行打开门动作# who.open_door(self.target)self.status = "success"

叶子节点:条件节点


# 叶子节点-条件节点:检查是否饥饿
class CheckHungryNode(BaseNode):def __init__(self, hungry_val):super(CheckHungryNode).__init__()self.hungry_val = hungry_val  # 生命值阈值def execute(self, who):# 检查生命值是否小于阈值if self.hungry_val > who.hungry_val:self.status = "success"else:self.status = "failure"# 叶子节点-条件节点:检查是否有食物
class CheckHasFoodNode(BaseNode):def __init__(self, food):super(CheckHasFoodNode).__init__()self.food = food  # 目标食物def execute(self, who):# 检查目标距离是否小于最大距离if who.has_food(self.food):self.status = "success"else:self.status = "failure"# 叶子节点-条件节点:敌人是否在周围
class CheckEnemiesAroundNode(BaseNode):def __init__(self, enemies):super(CheckEnemiesAroundNode).__init__()self.enemies = enemies  # 敌人def execute(self, who):# 敌人是否在周围if who.AroundHasEnemies(self.enemies):self.status = "success"else:self.status = "failure"

组合控制节点:序列节点

# 组合控制节点:序列节点
class SequenceNode(BaseNode):def __init__(self, children):super(SequenceNode).__init__()self.children = children  # 子节点列表def execute(self, who):for child in self.children:child.execute(who)if child.status == "failure":self.status = "failure"returnself.status = "success"

组合控制节点:选择节点

# 组合控制节点:选择节点
class SelectorNode(BaseNode):def __init__(self, children):super(SelectorNode).__init__()self.children = childrendef execute(self, who):for child in self.children:child.execute(who)if child.status == "success":self.status = "success"returnself.status = "failure"

装饰节点:逆变节点

# 装饰节点,逆变节点
class NOT_DecoratorNode(BaseNode):def __init__(self, child):super(DecoratorNOT).__init__()self.child = childdef execute(self, who):                      status = self.child.execute(who)if status == "success"self.status = "failure"elif status == "failure":self.status = "success"

例子一:

饥饿的时候,且有食物的时候,没有敌人在周围,就吃食物

# 角色对象
class Player(object):def __init__(self):self.hungry_val = 0  # 饥饿度self.food = "fish"  # 食物def main():# 首先定义行为树的结构root = SequenceNode([# 饥饿的时候CheckHungryNode(50),# 有鱼时候CheckHasFoodNode("fish"),# 敌人不在周围NOT_DecoratorNode(CheckEnemiesAroundNode("李宏伟")),# 老墨吃鱼EatFoodNode("fish"),])who = Player()# 然后在主循环中执行行为树while True:# 执行行为树root.execute(who)# 根据行为执行结果更新状态if root.status == "success":who.hungry_val = random.randint(1, 100)who.food = random.randint(1, 100)# 等待一段时间后再次执行行为树time.sleep(1)

例子二:

	# 行为树的结构如下root = SequenceNode([WalkToDoor(),SelectorNode([OpenDoor(),SequenceNode([UnlockDoor(),OpenDoor("self"),]),SmashDoor(),]),WalkThroughDoor(),CloseDoor(),		])

相关文章:

游戏算法-游戏AI行为树,python实现

参考文章:Behavior trees for AI: How they work (gamedeveloper.com) 本文主要参考上述weizProject Zomboid 的开发者 Chris Simpson文章的概念,用伪代码实现代码例子 AI概述 游戏AI是对游戏内所有非玩家控制角色的行为进行研究和设计,使得游…...

【新2023Q2模拟题JAVA】华为OD机试 - 矩阵最值 or 计算二维矩阵的最大值

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:矩阵最值 or 计算二维矩阵的最…...

递归过程与递归工作栈

首先了解一下任意两个函数之间进行调用的情况: 比如在a函数里面调用b函数,那么在使用b函数之前,计算机还会1.把实参,返回地址给复制下来(但只是复制而已,地址不是原来的。)如图: 此外2.为被调用…...

B 树的简单认识

理解 B 树的概念 B 树是一种自平衡的查找树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除数据的动作,都能在对数时间内完成。 同一般的二叉查找树不同,B 树是一棵多路平衡查找树,其特性是&#xff…...

【大数据Hive3.x数仓开发】窗口函数案例:连续N次登录的用户;级联累加求和;分组TopN

文章目录1 统计连续N次登录的用户(N>2)自连接过滤实现窗口函数lead()实现2 级联累加求和自连接窗口函数sum()实现3 分组TopN问题对窗口函数的讲解part见:【大数据Hive3.x数仓开发】函数–窗口函数 1 统计连续N次登录的用户(N&…...

openpyxl库自动填充excel实例分享

openpyxl可以通过编写Python脚本实现自动化Excel操作,包括自动填充数据、格式化单元格、生成图表等操作。 以下是一个常见的自动化Excel操作示例: 自动填充数据: from openpyxl import Workbook from openpyxl.utils import get_column_l…...

ICLR2021清华团队做的知识蒸馏提升detector的点的工作paper 小陈读论文系列

这个作者栏目就是一个词 清爽 牛逼不需要花里胡哨哈哈 无疑是有点tian了哈哈 不重要 毕竟有机会研读 梦中情笑的paper 还是很感激的 真的 很清爽啊 很多KD的工作确实 在下游任务呢效果不是很好 然后就引出了自己的关于提升知识蒸馏在OD方面的工作 OD 首先就有两个问题 1.前…...

Java核心技术知识点笔记—集合框架

前言:Java最初版本只为最常用的数据结构提供了很少的一组类:Vector、Stack、Hashtable、BitSet和Enumeration接口。其中,Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制。与现代数据结构类库常见情况一样,Java集…...

Rsync数据同步工具

一、什么是Rsync Rsync是一款开源的,快速的,多功能的,可实现全量及增量(差异化备份)的本地或远程数据同步备份的优秀工具。 Rsync软件适用于Unix、Linux、Windows等多种操作系统。 (1)可使本地…...

redux小结

store.dispatch(action对象) 在 dispatch 中调用 action 方法返回 action 对象 // /actions/index.js /*** Action:* action本质上是一个 JS 对象;* 必须要包含 type 属性,否则会报错;* 只描述了有事情要发生&#xff0c…...

【Python】【进阶篇】十、Pygame的Font文本和字体

目录十、Pygame的Font文本和字体10.1 font.SysFont()10.2 font.Font()10.3 字体对象方法十、Pygame的Font文本和字体 Pygame 通过pygame.font模块来创建一个字体对象,从而实现绘制文本的目的。 该模块的常用方法如下所示: 名称说明pygame.font.init()初…...

【从零开始学习 UVM】10.8、UVM TLM —— UVM TLM Example

文章目录 subComp1subComp2ComponentAsubComp3ComponentBTop Env/Test这个 UVM TLM 示例使用之前文章中讨论的 put 端口、TLM FIFO 和 get 端口来构建一个具有不同层次的 TLM 端口的测试台。 下面定义了一个名为Packet的类,作为从一个组件传输到另一个组件的数据项。这个类对象…...

获取自己所上传资源的下载量

import requestsurl = https://download-console-api.csdn.net/v1/user/sources/getUploadListByUserName?status=2&pageNum=1&pageSize=100 cookie = # 这里填自己的cookie header = {"authority": "download-console-api.csdn.net","met…...

Aspose.cells模板导出使用记录

简述 用Aspose.cells导出可以方便地将数据到Excel文档中,简单的直接将DataTable列表写入即可,复杂的格式一般会先做好模板,再将数据填充进去,这样可以保持设置好的样式,又能快速填充内容,十分方便。 智能…...

AcWing——糖果传递

有 n个小朋友坐成一圈,每人有 a[i]个糖果。 每人只能给左右两人传递糖果。 每人每次传递一个糖果代价为 1。 求使所有人获得均等糖果的最小代价。 输入格式 第一行输入一个正整数 n,表示小朋友的个数。 接下来 n 行,每行一个整数 a[i]&…...

Redis中的单线程模型

文章目录 文件事件处理器模型Redis的客户端与服务端的交互过程图Redis基于Reactor模式开发了自己的网络事件处理器,称之为 文件事件处理器(File Event Hanlder)。 文件事件处理器由Socket、IO多路复用程序文件事件分派器(dispather)事件处理器(handler)文件事件处理器模型 IO…...

Python函数默认参数设置(超级详细)

我们知道,在调用函数时如果不指定某个参数,Python 解释器会抛出异常。为了解决这个问题,Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话,即便调用函数时没有给拥有默…...

人工智能如何赋能业务创新?安克创新有话要说

对于一家企业来说,应该如何运用人工智能技术助力业务创新?作为一家多年复合增长率超过35%的企业,安克创新对这个话题无疑有着深切的体验感悟。飞速成长的消费电子企业众所周知,当下各行各业都在如火如荼地开展人工智能应用&#x…...

如何学习与学习的本质

如何学习两种模式两种记忆方式拖延问题学习方法学习本质两种模式 专注模式发散模式 专注模式和发散模式可以进行切换,提高效率, 发散模式可以后台工作。 两种记忆方式 工作记忆(前额叶皮质)长时记忆(图像比较容易记…...

C++ deque容器

C deque容器 文章目录C deque容器前言1. deque容器基本概念2. deque构造函数3. deque赋值操作4. deque大小操作5. deque 插入和删除6. deque 数据存取7. deque 排序总结前言 本文包含deque容器基本概念、deque构造函数、deque赋值操作、deque大小操作、deque插入和删除、deque…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...