游戏AI的创造思路-技术基础-决策树(2)

上一篇写了决策树的基础概念和一些简单例子,本篇将着重在实际案例上进行说明

目录

8. 决策树应用的实际例子

8.1. 方法和过程

8.1.1. 定义行为

8.1.2. 确定属性

8.1.3. 构建决策树

8.1.4. 实施行为

8.1.5. 实时更新

8.2. Python代码


8. 决策树应用的实际例子

模拟空战游戏中,AI使用决策树算法,控制多个NPC敌方战机协同攻击玩家。

8.1. 方法和过程

8.1.1. 定义行为

敌方战机可能的行为包括:进攻、防守、掩护、撤退等。

8.1.2. 确定属性

影响决策的属性可能包括:

敌方战机的数量、位置、速度、武器状态

玩家战机的位置、速度、武器状态等

8.1.3. 构建决策树

根据属性构建决策节点,例如:

  • 如果敌方战机数量大于玩家,且敌方战机位置靠近玩家,则选择进攻。
  • 如果敌方战机数量少于玩家,且敌方战机位置分散,则选择掩护和撤退。
  • 如果敌方战机有优势武器,则选择优先使用优势武器进攻。
  • 考虑敌机的武器状态和剩余弹药:在决定使用哪种武器进攻时,应该考虑武器的可用性和剩余弹药。
  • 考虑盟友和敌人的位置:在决定行动时,应该考虑盟友和敌人的相对位置,以避免友军伤害和优先攻击较弱的敌人。
  • 增加撤退逻辑:当敌机健康状态很低时,应该优先考虑撤退而不是进攻。
  • 引入随机性:在决策过程中引入一些随机性,使得敌机的行为更加难以预测。
  • 优化机动规避逻辑:机动规避时,应该考虑玩家的位置和速度,以便更有效地规避攻击。
  • 协同策略
    • 制定敌方战机之间的协同策略,例如:
    • 分配攻击目标,确保每架敌方战机都有明确的攻击对象。
    • 制定掩护策略,保护处于劣势的战机。
    • 制定撤退策略,当战机受损严重时撤退。

8.1.4. 实施行为

根据决策树的结果,敌方战机执行相应的行为。

8.1.5. 实时更新

战场环境是实时变化的,因此需要不断更新属性,并重新进行决策。

8.2. Python代码

 在这个实现中,EnemyFighter类代表敌方战机,具有ID、位置、速度和武器状态等属性。

EnemyFighter类中的health属性用来表示敌方战机的健康状态。decide_action方法现在考虑了更多的因素,包括战机的健康状态、与玩家的距离、敌方和盟友的数量,以及武器的状态。

EnemyFighter类的position属性现在是一个三维坐标。distance_to方法用于计算三维空间中的距离。

EnemyFighter类的evade方法,用于进行机动规避、加速,并快速改变自身所在位置。

decide_action方法现在会在距离目标小于23000时调用evade方法,并执行相应的规避动作。

EnemyFighter类用choose_weapon方法来根据距离选择合适的武器,并且在decide_action方法中考虑了武器的可用性和剩余弹药。

最后,我们模拟了一个战场环境,并让每架敌方战机做出决策。

以下上代码

import math  
import random  class EnemyFighter:  def __init__(self, id, position, speed, weapon_status, health, ammo):  self.id = id  self.position = position  # (x, y, z)  self.speed = speed  self.weapon_status = weapon_status  # 字典,包含武器名称和状态  self.health = health  self.ammo = ammo  # 字典,包含武器名称和剩余弹药  def distance_to(self, other_position):  return math.sqrt((self.position[0] - other_position[0])**2 +  (self.position[1] - other_position[1])**2 +  (self.position[2] - other_position[2])**2)  def choose_weapon(self, distance_to_player):  available_weapons = [weapon for weapon, status in self.weapon_status.items() if status == "可用"]  if not available_weapons:  return None  # 根据距离选择合适的武器  if distance_to_player <= 500:  return "机炮"  elif 500 < distance_to_player <= 5000:  return "近距空空弹"  elif 5000 < distance_to_player <= 23000:  return "中距空空弹"  elif 23000 < distance_to_player <= 100000:  return "远程空空弹"  return None  def evade(self, player_position):  max_evade_distance = 500  evade_direction = (random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1))  evade_distance = random.uniform(0, max_evade_distance)  self.position = (  self.position[0] + evade_direction[0] * evade_distance,  self.position[1] + evade_direction[1] * evade_distance,  self.position[2] + evade_direction[2] * evade_distance  )  self.speed *= 1.5  def decide_action(self, player_position, allies, enemies):  if self.health < 30:  return "撤退"  distance_to_player = self.distance_to(player_position)  weapon = self.choose_weapon(distance_to_player)  if distance_to_player < 23000:  self.evade(player_position)  return "机动规避,加速,并快速改变位置"  if weapon:  if self.ammo[weapon] > 0:  return f"使用{weapon}进攻"  else:  return "武器弹药耗尽,寻找补给或撤退"  return "等待时机接近目标或寻找其他敌人"  # 模拟战场环境 
player_position = (5000, 5000, 0)  
enemies = [  EnemyFighter(1, position=(1000, 1000, 0), speed=100, weapon_status="全武器可用", health=100),  EnemyFighter(2, position=(1500, 1500, 0), speed=120, weapon_status="全武器可用", health=80),  EnemyFighter(3, position=(2000, 2000, 0), speed=110, weapon_status="全武器可用", health=60)  
]  
allies = [  EnemyFighter(4, position=(3000, 3000, 0), speed=100, weapon_status="全武器可用", health=100),  EnemyFighter(5, position=(3500, 3500, 0), speed=100, weapon_status="全武器可用", health=90)  
]  # 敌方战机做出决策  
for enemy in enemies:  action = enemy.decide_action(player_position, allies, enemies)  print(f"敌方战机{enemy.id}(位置:{enemy.position},健康:{enemy.health})决定:{action}")

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

滑动窗口,最长子序列最好的选择 -> O(N)

最近在学校上短学期课程&#xff0c;做程序设计题&#xff0c;一下子回忆起了大一学数据结构与算法的日子&#xff01; 这十天我会记录一些做题的心得&#xff0c;今天带来的是对于最长子序列长度题型的解题框架&#xff1a;滑动窗口 本质就是双指针算法&#xff1a; 通过le…

Vue路由传参和接参如何实现

在Vue中&#xff0c;使用Vue Router进行页面路由跳转时&#xff0c;经常需要传递参数到目标页面&#xff08;组件&#xff09;并在目标页面&#xff08;组件&#xff09;中接收这些参数。Vue Router提供了几种方式来实现路由传参和接参&#xff0c;主要包括通过URL的查询参数&a…

模拟生成高斯随机数序列

模拟和生成高斯随机数序列&#xff08;服从标准正态分布的随机变量&#xff09; Box-Muller 法 & Marsaglia 极坐标法 Box-Muller&#xff1a;使两个独立的均匀分布生成一个高斯分布。 Box-Muller方法的基本思想是利用两个独立的均匀分布随机变量的关系来生成高斯分布的…

Elasticsearch 多索引/多类型搜索

Elasticsearch&#xff0c;简称ES&#xff0c;是一个建立在Apache Lucene基础上的开源搜索引擎&#xff0c;它支持近乎实时的数据存储和检索&#xff0c;并具有良好的扩展性&#xff0c;可以处理PB级别的数据。在复杂的应用场景中&#xff0c;经常需要跨多个索引或类型进行搜索…

AcWing 1633:外观数列

【题目来源】https://www.acwing.com/problem/content/1635/【题目描述】 外观数列是指具有以下特点的整数序列&#xff1a;D, D1, D111, D113, D11231, D112213111, ...其中 D 是一个 [0,9] 范围内的不等于 1 的整数。 序列的第 n1 项是对第 n 项的描述。比如&#xff1a; 第 …

编程语言成长经历:探索、挑战与蜕变

编程语言成长经历&#xff1a;探索、挑战与蜕变 在数字化时代&#xff0c;编程语言无疑成为了连接人与机器的重要桥梁。回首我的编程语言成长经历&#xff0c;仿佛是一段充满探索、挑战与蜕变的旅程。 四个方面&#xff1a;初识编程的迷茫与好奇 当我第一次接触编程语言时&a…

Ubuntu与Windows通过WIFI与以太网口共享网络,Ubuntu与Windows相互ping通,但ping百度失败

Linux开发板&#xff08;正点原子阿尔法_IMX6U&#xff09;与Ubuntu的文件传输SCP 报错 SSH: no matching host key type found. Their offer: ssh-rsa-CSDN博客 前面的文章提到了如何将Ubuntu与Windows通过WIFI共享网络给以太网&#xff0c;从而实现Linux开发板、Ubuntu、Win…

香港优才计划续签难吗?一次性说清楚优才续签要求,不在香港居住也能续签成功!

香港优才计划续签难吗&#xff1f;这个问题对考虑申请优才的人来说&#xff0c;还是挺重要的。我们申请优才&#xff0c;最关注的2个问题&#xff0c;一个是获批&#xff0c;还有一个就是续签了。 毕竟我们费那么大功夫申请优才&#xff0c;可不只是为了一个为期3年的香港临时…

数据结构第20节 快速排序以及优化

快速排序是一种非常高效的排序算法&#xff0c;由英国计算机科学家托尼霍尔&#xff08;Tony Hoare&#xff09;在1960年代发明。它使用分治法&#xff08;Divide and Conquer&#xff09;策略来把一个序列分为较小的部分&#xff0c;然后递归地排序这些部分。 快速排序的基本…

Python 实现Word文档中提取表格数据并转换为CSV和JSON格式

python实现Word文档中提取表格数据 前言1.解析Word文档中的表格2.保存表格数据3.处理文件夹中的多个Word文档4.总结 前言 在日常工作中&#xff0c;我们经常需要处理大量的Word文档&#xff0c;其中包含各种表格数据。手动整理这些表格不仅耗时且容易出错。因此&#xff0c;开…

如何分析软件测试中发现的Bug!

假如你是一名软件测试工程师&#xff0c;每天面对的就是那些“刁钻”的Bug&#xff0c;它们像是隐藏在黑暗中的敌人&#xff0c;时不时跳出来给你一个“惊喜”。那么&#xff0c;如何才能有效地分析和处理这些Bug&#xff0c;让你的测试工作变得高效且有趣呢&#xff1f;今天我…

MongoDB - 集合和文档的增删改查操作

文章目录 1. MongoDB 运行命令2. MongoDB CRUD操作1. 新增文档1. 新增单个文档 insertOne2. 批量新增文档 insertMany 2. 查询文档1. 查询所有文档2. 指定相等条件3. 使用查询操作符指定条件4. 指定逻辑操作符 (AND / OR) 3. 更新文档1. 更新操作符语法2. 更新单个文档 updateO…

【ElasticSearch】ES 5.6.15 向量插件支持

参考 : https://github.com/lior-k/fast-elasticsearch-vector-scoring 下载插件 安装插件 插件目录&#xff1a; elasticsearch/plugins, 安装后的目录如下 plugins└── vector├── elasticsearch-binary-vector-scoring-5.6.9.jar└── plugin-descriptor.properties修…

linux中如何开启多个mysql进城并且单独设置密码和端口

在 Linux 系统中&#xff0c;默认情况下 MySQL&#xff08;或 MariaDB&#xff0c;一个流行的 MySQL 分支&#xff09;不直接支持在同一台机器上运行多个 MySQL 实例&#xff0c;每个实例使用不同的端口和独立的密码系统。但是&#xff0c;你可以通过配置多个 MySQL 实例&#…

web安全及内网安全知识

本文来源无问社区&#xff08;wwlib.cn&#xff09;更多详细内容可前往观看http://www.wwlib.cn/index.php/artread/artid/7506.html Web安全 1、sql注入 Web程序中对于用户提交的参数未做过滤直接拼接到SQL语句中执行&#xff0c;导致参数中的特殊字符破坏了SQL语句原有逻…

简述多云互联原理,客户公私云池互通的产品是什么?

多云互联原理基于企业或组织使用多个不同的云服务提供商的基础设施和服务&#xff0c;以实现最佳的运营效率、弹性和成本效益。这种策略允许用户避免供应商锁定&#xff0c;分散风险&#xff0c;并利用不同云服务商的特定优势&#xff0c;例如价格、地理位置、功能或性能。 多云…

jvm 07 GC算法,内存池,对象内存分配

01 垃圾判断算法 1.1引用计数算法 最简单的垃圾判断算法。在对象中添加一个属性用于标记对象被引用的次数&#xff0c;每多一个其他对象引用&#xff0c;计数1&#xff0c; 当引用失效时&#xff0c;计数-1&#xff0c;如果计数0&#xff0c;表示没有其他对象引用&#xff0c;…

【LeetCode】字母异位词分组

目录 一、题目二、解法完整代码 一、题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, …

51单片机-第一节-LED和独立按键

一、点亮LED&#xff1a; 首先包含头文件 <REGX52.H> 随后令P2为0xFE。(此时二进制对应1111 1110&#xff0c;为0 的LED亮&#xff0c;故八个灯中的最后一个亮起)。 注&#xff1a;P2为控制LED的8位寄存器。 void main() {P2 0xFE;//1111 1110while(1){} } 二、L…

递归 汉诺塔-java

汉诺塔传说&#xff1a; 汉诺塔&#xff08;又称河内塔&#xff09;问题是源于印度一个古老传说的益智玩具。 大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一个柱子从下往上按照大小顺序摞着64片圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱…