游戏算法-游戏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 运行 running

	def 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"
				return
		self.status = "success"



组合控制节点:选择节点

# 组合控制节点:选择节点
class SelectorNode(BaseNode):
	def __init__(self, children):
		super(SelectorNode).__init__()
		self.children = children

	def execute(self, who):
		for child in self.children:
			child.execute(who)
			if child.status == "success":
				self.status = "success"
				return
		self.status = "failure"

装饰节点:逆变节点

# 装饰节点,逆变节点
class NOT_DecoratorNode(BaseNode):
	def __init__(self, child):
		super(DecoratorNOT).__init__()
		self.child = child
	
	def 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(),		
	])
	

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/6327.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子拣货标签9代系统简介

CK_Label_v9一、产品参数 产品型号 CK_Label_v9 LED 3(红&黄&绿)独立可控 供电方式 DC 24V 0.2A 通信方式 无线通信 蜂鸣器 支持 尺寸 D60 H307mm 二、革新点 配合标签拣货使用三个灯(红黄绿)都可以被独立控…

基于MATALB编程的BP神经网络手臂血管分类识别,基于BP神经网络的图像分类

目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 数据 神经网络参数 基于BP神经网络手臂血管识别的MATLAB代码 效果图 结果分析 展望 背影 随着人工智能的发展,智…

贪心算法-删数问题C++

目录 一、题目 二&#xff1a;思路 代码 运行结果 一、题目 有一个长度为n&#xff08;n < 240&#xff09;的正整数&#xff0c;从中取出k&#xff08;k < n&#xff09;个数&#xff0c;使剩余的数保持原来的次序不变&#xff0c;求这个正整数经过删数之后最小是多…

用Python绘制六种可视化图表,简直太好用了

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python资料、源码、教程: 点击此处跳转文末名片获取 可视化图表&#xff0c;有相当多种&#xff0c;但常见的也就下面几种&#xff0c;其他比较复杂一点&#xff0c;大都也是基于如下几种进行组合&#xff0c;变换出来的。 …

记录--CSS 如何实现羽化效果?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近碰到这样一个问题&#xff0c;在一张封面上直接显示书名&#xff0c;可能会存在书名看不太清楚的情况(容易受到背景干扰)&#xff0c;如下 为了解决这个问题&#xff0c;设计师提了一个“究极”方…

算法 - 希尔排序

原理 首先将数组两两分组&#xff0c;分成n组数组&#xff0c;每组数组内部进行排序。再分成n/2组数组&#xff0c;每组数组内部进行排序。直至分成只剩一组&#xff0c;最后进行排序得到最后的数组。 代码 public static int[] shell(int[] arr) {int temp;for (int gra …

计算机图形学13:三维图形的几何变换

作者&#xff1a;非妃是公主 专栏&#xff1a;《计算机图形学》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录专栏推荐专栏系列文章序一、三维图形的几…

MongoDB综述【入门指南】

写这篇博客,正好是2023年4月5日15:29:31,是清明节,放假一天,我坐在我的小小租房室内,思考着没思考到啥,哈哈哈,感觉好着急啊!看完了一本《城南旧事》,但是就是不踏实,好吧~我来写一篇最近在学的一个技术 为了更优秀的自己~奥利给!! 首先,我们从最初级小白开始(因为自己也是小白…

卷麻了,00后测试用例写的比我还好,简直无地自容.....

前言 作为一个测试新人&#xff0c;刚开始接触测试&#xff0c;对于怎么写测试用例很头疼&#xff0c;无法接触需求&#xff0c;只能根据站在用户的角度去做测试&#xff0c;但是这样情况会导致不能全方位的测试APP&#xff0c;这种情况就需要一份测试用例了&#xff0c;但是不…

倾斜实景三维建模与BIM模型处理技术

倾斜实景三维建模与BIM模型处理技术 一、研究背景 ➢ 倾斜模型 ✓ 真实纹理&#xff0c;高分辨率 ✓ 真实坐标&#xff0c;高空间精度 ✓ 快速建模&#xff0c;低建模成本 ➢ BIM设计 BIM 技术作为建筑施工行业中的新技术&#xff0c;存在于建筑的全生命周期&#xff0c;服务…

机器学习算法:K近邻(k-nearest neighbors)初探

KNN的介绍和应用 KNN&#xff08;K-Nearest Neighbor&#xff09;算法是一种基于实例的学习算法&#xff0c;也是一种常见的分类算法。 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别&#xff0c;则该样本也属于这个类别。 示例 &…

Python 3 基本数据类型,包含示例演示(初学友好)

嗨害大家好鸭~ 我是芝士❤ 有好好学习python吗&#xff1f; Python学习资料电子书 点击此处跳转文末名片获取 Python3 基本数据类型 Python 中的变量不需要声明。每个变量在使用前都必须赋值&#xff0c;变量赋值以后该变量才会被创建。 在 Python 中&#xff0c;变量就是变量…

MATLAB 求解定积分和不定积分

本文主要介绍如何通过matlab 去求解常见的定积分和不定积分的结果&#xff0c;使用matlab 内置函数 int。 语法&#xff1a; Fint(表达式&#xff0c;变量&#xff0c;变量上下限) 目录 例子1 单变量不定积分 例子2 多变量不定积分 例子3 单变量定积分 例子4 定积分近似求…

软件测试高频出现面试题-2(实用)

每日面试1、自我介绍2、简单介绍最近项目你是如何开展测试工作的呢&#xff1f;3、描述在这个项目里面你主要负责哪些模块的测试&#xff1f;选中一个业务复杂的讲述你是如何测试的呢&#xff1f;1、自我介绍 主要可以从三个方面准备&#xff1a;我的基础信息&#xff0c;我的…

OBCP第八章 OB运维、监控与异常处理-常见异常处理

问题排查概述&#xff1a;数据库连接问题排查 在遇到连接问题时&#xff0c;需要清楚整个系统的架构&#xff0c;对整个连接链路进行排查。通常情况下应用连接到数据库的完整链路是从应用服务器到 OBProxy 再到 OB 集群&#xff0c;此外还可能涉及负载均衡、DNS 解析、网络等。…

49天精通Java,第24天,Java链表、散列表、HashSet、TreeSet

目录一、链表二、散列表三、HashSet四、TreeSet五、TreeSet常用方法大家好&#xff0c;我是哪吒。 一、链表 从数组中间删除一个元素开销很大&#xff0c;其原因是向数组中插入元素时&#xff0c;此元素之后的所有元素都要向后端移动&#xff0c;删除时也是&#xff0c;数组中…

大厂面试篇--2023软件测试八股文最全文档,有它直接大杀四方

前言 已经到了金三银四的黄金招聘季节了&#xff0c;还在准备面试跳槽涨薪的小伙伴们可以看看本篇文章哟&#xff0c;这里呢笔者就不多说废话了直接上干货&#xff01;答案已整理好&#xff0c;文末拿去即可&#xff01;非常好用&#xff01; 一、字节跳动测试面经篇 1、在搜…

【KNN算法详解(用法,优缺点,适用场景)及应用】

KNN算法介绍 KNN&#xff08;K Near Neighbor&#xff09;&#xff1a;k个最近的邻居&#xff0c;即每个样本都可以用它最接近的k个邻居来代表。KNN算法属于监督学习方式的分类算法&#xff0c;我的理解就是计算某给点到每个点的距离作为相似度的反馈。 简单来讲&#xff0c;…

【工具】Maven

文章目录0.Maven安装&#xff08;不使用IDEA内置&#xff09;1.Maven的作用2.Maven核心概念3.maven目录结构4.仓库5.pom文件5.1 坐标 gav5.2.packaging5.3.依赖5.4.配置属性5.5.build6.Maven生命周期7.junit 单元测试8.插件9.IDEA构建Maven10.创建javase项目11.web工程12.依赖的…

【Linux】初识动静态库/动静态链接

文章目录动静态库的基本原理认识动静态库动静态库的特性手动安装静态库动静态库的基本原理 首先&#xff0c;文件和头文件最终变成一个可执行程序需要经历以下四个步骤&#xff1a; 1&#xff09;预处理&#xff1a;预处理所要完成的有&#xff0c;头文件展开、去注释、宏替换…