游戏AI的创造思路-技术基础-蒙特卡洛树搜索(2)

接上一篇,让我们来看更多的例子

目录

7. 更多例子

7.1. 国际象棋实例

7.2. RTS类游戏实例

7.3. FPS类游戏实例


7. 更多例子

蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)在游戏AI中有着广泛的应用,尤其是在那些具有巨大状态空间和复杂决策过程的游戏中。

除了围棋,MCTS还被应用于国际象棋、五子棋、扑克牌游戏(如德州扑克)、甚至在一些实时策略游戏(如《星际争霸II》)的AI中也使用了MCTS或其变种。

7.1. 国际象棋实例

以下是一个使用Python实现的MCTS在国际象棋中的应用实例。

这个示例是一个简化的版本,主要用于演示MCTS的基本框架和算法流程。

请注意,由于国际象棋的完整规则相当复杂,这里的实现仅涵盖了MCTS的核心部分,并未包括完整的游戏逻辑和胜负判断。

import random  
from math import sqrt, log  
import chess  # 使用python-chess库来处理国际象棋的游戏逻辑  class Node:  def __init__(self, game_state, parent=None):  self.game_state = game_state  self.parent = parent  self.children = []  self.visits = 0  self.wins = 0  self.untried_moves = list(game_state.legal_moves)  def is_terminal(self):  return self.game_state.is_game_over()  def uct_value(self, parent_visits):  if self.visits == 0:  return float('inf')  win_rate = self.wins / self.visits  exploration_factor = sqrt(2)  return win_rate + exploration_factor * sqrt(log(parent_visits) / self.visits)  def expand(self):  move = self.untried_moves.pop()  next_state = self.game_state.copy()  next_state.push(move)  child_node = Node(next_state, self)  self.children.append(child_node)  return child_node  def select_child(self):  return max(self.children, key=lambda child: child.uct_value(self.visits))  def simulate(node):  current_node = node  while not current_node.is_terminal():  if current_node.untried_moves:  current_node = current_node.expand()  else:  current_node = current_node.select_child()  return current_node.game_state.result()  def backpropagate(node, result):  while node:  node.visits += 1  if result == '1-0':  # 白方胜  node.wins += 1  elif result == '0-1':  # 黑方胜  node.wins += 0  # 这里实际上不需要加0,只是为了保持格式一致  node = node.parent  def mcts(root, num_iterations):  for _ in range(num_iterations):  node = root  while not node.is_terminal():  if node.untried_moves:  node = node.expand()  else:  node = node.select_child()  result = simulate(node)  backpropagate(node, result)  # 示例用法  
board = chess.Board()  
root = Node(board)  
num_iterations = 1000  
mcts(root, num_iterations)  
best_child = max(root.children, key=lambda child: child.visits)  
print("推荐走子:", best_child.game_state.peek())  
print("访问次数:", best_child.visits)

在这个示例中,我们使用了python-chess库来处理国际象棋的游戏逻辑。

Node类表示MCTS中的一个节点,它包含了游戏状态、父节点、子节点列表、访问次数、胜利次数以及未尝试的走子列表。

mcts函数实现了MCTS算法的主要流程,包括选择、扩展、模拟和反向传播。

在示例用法中,我们创建了一个初始的游戏状态,并进行了1000次MCTS迭代来选择最佳的走子。最后,我们打印了推荐的走子和它的访问次数。

7.2. RTS类游戏实例

蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)在即时战略(RTS)游戏AI中的应用相对复杂,因为RTS游戏具有巨大的状态空间和复杂的实时决策需求。

以下是一个简化的MCTS在RTS游戏AI中的应用实例,涵盖了游戏单位的移动、走位、攻击、使用魔法和撤退等基本操作。

由于完整的RTS游戏环境(如《星际争霸II》或《魔兽争霸III》)的代码实现非常复杂,且通常需借助游戏特定的API(例如《星际争霸II》的PySC2)来交互,这里将使用一个简化的模拟环境来演示MCTS的应用。我们将创建一个简化的RTS游戏状态类,并在其上实现MCTS,你可以基于此框架,结合具体的RTS游戏API,进行进一步的开发。

以下是一个简化的MCTS算法Python代码:

import random  
from math import sqrt, log  class RTSGameState:  def __init__(self):  # 简化状态表示,实际应包含所有游戏单位的状态  self.units = [  {"type": "warrior", "health": 100, "position": (0, 0)},  {"type": "mage", "health": 80, "position": (1, 1), "mana": 100},  # ... 其他单位  ]  self.enemy_units = [  {"type": "enemy_warrior", "health": 100, "position": (10, 10)},  # ... 其他敌方单位  ]  self.turn = 0  # 游戏回合数  def is_game_over(self):  # 简化判断,实际应包含复杂的游戏结束条件  return False  def legal_moves(self):  # 返回所有合法动作,这里仅作为示例  return ["move_up", "move_down", "move_left", "move_right", "attack", "use_magic", "retreat"]  def copy(self):  # 深拷贝游戏状态  return RTSGameState()  # 实际应用中需要实现深拷贝逻辑  def apply_move(self, move):  # 应用动作到游戏状态,这里仅作为示例  if move == "move_up":  self.units[0]["position"] = (self.units[0]["position"][0], self.units[0]["position"][1] + 1)  # ... 其他动作的逻辑  def result(self):  # 返回游戏结果,这里仅作为示例  return "ongoing"  # 或 "win", "lose"  class Node:  def __init__(self, game_state, parent=None, move=None):  self.game_state = game_state  self.parent = parent  self.move = move  self.children = []  self.visits = 0  self.total_reward = 0  self.untried_moves = game_state.legal_moves()def select_child(self):  # 使用UCT选择子节点  scores = [(child.total_reward / child.visits) + sqrt(2 * log(self.visits) / child.visits)  for child in self.children]  return self.children[scores.index(max(scores))]  def expand(self):  # 展开节点,随机选择一个未尝试的动作  move = random.choice(self.untried_moves)  new_game_state = self.game_state.copy()  new_game_state.apply_move(move)  child_node = Node(new_game_state, self, move)  self.children.append(child_node)  self.untried_moves.remove(move)  return child_node  def update(self, result):  # 更新节点的访问次数和总奖励  self.visits += 1  self.total_reward += result  def __repr__(self):  return f"[M:{self.move} V:{self.visits} R:{self.total_reward}]"  def simulate(node):  # 简化模拟:随机选择动作直至游戏结束  while not node.game_state.is_game_over():  move = random.choice(node.game_state.legal_moves())  node.game_state.apply_move(move)  return node.game_state.result()  def backpropagate(node, result):  # 反向传播模拟结果  while node:  node.update(result)  node = node.parent  def mcts(root, num_iterations):  for _ in range(num_iterations):  node = root  # 选择  while node.untried_moves == [] and node.children != []:  node = node.select_child()  # 展开  if node.untried_moves != []:  node = node.expand()  # 模拟  result = simulate(node)  # 反向传播  backpropagate(node, result)  # 示例用法  
game_state = RTSGameState()  
root = Node(game_state)  
num_iterations = 1000  
mcts(root, num_iterations)  
best_child = max(root.children, key=lambda child: child.visits)  
print("推荐动作:", best_child.move)  
print("访问次数:", best_child.visits)

RTSGameState类是一个抽象基类,你需结合具体的RTS游戏API来实现它。

apply_move方法应修改游戏状态,legal_moves方法应返回当前状态下的合法动作列表,is_game_over方法应判断游戏是否已结束,而result方法则应返回游戏的结果。

7.3. FPS类游戏实例

蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)在第一人称射击游戏(FPS)的AI队友中实现是一个复杂的任务,涉及对游戏环境的深入理解、与游戏引擎的交互以及AI算法的实现。由于FPS游戏的复杂性和多样性,这里只能提供一个简化的MCTS实现框架,并不能直接应用于具体的游戏,如《CS:GO》或《守望先锋》。你需要根据具体游戏的环境和API来调整和完善这个框架。

以下是一个简化的MCTS算法框架,用于FPS游戏中AI队友的决策:

import random  
from math import sqrt, log  # 假设存在一个与游戏交互的API模块,这里我们使用一个模拟的游戏API  
class GameAPI:  # 假设游戏状态是一个字典,包含玩家的位置、敌人的位置和玩家的生命值  game_state = {  'player_position': (0, 0),  'enemy_positions': [(10, 10)],  'player_health': 100  }  @staticmethod  def get_game_state():  # 返回当前游戏状态的副本  return GameAPI.game_state.copy()  @staticmethod  def is_game_over():  # 判断游戏是否结束,例如玩家生命值小于等于0  return GameAPI.game_state['player_health'] <= 0  @staticmethod  def get_available_actions():  # 返回当前游戏状态下可用的动作列表  return ['move_forward', 'move_backward', 'move_left', 'move_right', 'shoot', 'throw_grenade', 'retreat']  @staticmethod  def apply_action(action):  # 应用动作到游戏状态  if action == 'move_forward':  GameAPI.game_state['player_position'] = (GameAPI.game_state['player_position'][0] + 1, GameAPI.game_state['player_position'][1])  elif action == 'move_backward':  GameAPI.game_state['player_position'] = (GameAPI.game_state['player_position'][0] - 1, GameAPI.game_state['player_position'][1])  elif action == 'move_left':  GameAPI.game_state['player_position'] = (GameAPI.game_state['player_position'][0], GameAPI.game_state['player_position'][1] - 1)  elif action == 'move_right':  GameAPI.game_state['player_position'] = (GameAPI.game_state['player_position'][0], GameAPI.game_state['player_position'][1] + 1)  elif action == 'shoot':  # 假设射击总是成功的,并减少一个敌人的生命值(这里简单模拟为移除一个敌人)  if GameAPI.game_state['enemy_positions']:  GameAPI.game_state['enemy_positions'].pop(0)  elif action == 'throw_grenade':  # 假设投掷手榴弹会立即结束游戏(模拟玩家自杀)  GameAPI.game_state['player_health'] = 0  elif action == 'retreat':  # 假设撤退会恢复一些生命值  GameAPI.game_state['player_health'] += 10 if GameAPI.game_state['player_health'] < 100 else 0  @staticmethod  def get_reward():  # 返回执行动作后的奖励  if GameAPI.is_game_over():  return -100  # 游戏结束,返回大负值作为惩罚  enemies_remaining = len(GameAPI.game_state['enemy_positions'])  return -enemies_remaining  # 敌人越少,奖励越高(负值表示我们想要最小化这个数量)   class Node:  def __init__(self, game_state, parent=None, action=None):  self.game_state = game_state  self.parent = parent  self.action = action  self.children = []  self.visits = 0  self.total_reward = 0  self.untried_actions = game_state.get_available_actions()  def select_child(self):  scores = [(child.total_reward / child.visits) + sqrt(2 * log(self.visits) / child.visits) if child.visits > 0 else float('inf')  for child in self.children]  return self.children[scores.index(max(scores))]  def expand(self):  action = random.choice(self.untried_actions)  new_game_state = self.game_state.copy()  new_game_state.apply_action(action)  child_node = Node(new_game_state, self, action)  self.children.append(child_node)  self.untried_actions.remove(action)  return child_node  def update(self, result):  self.visits += 1  self.total_reward += result  def __repr__(self):  return f"[A:{self.action} V:{self.visits} R:{self.total_reward}]"  class GameState:  def __init__(self):  self.state = GameAPI.get_game_state()  def is_terminal(self):  return GameAPI.is_game_over()  def get_available_actions(self):  return GameAPI.get_available_actions()  def copy(self):  new_state = GameState()  # 这里应该深拷贝游戏状态,具体实现依赖于游戏状态的复杂性  new_state.state = self.state  # 假设游戏状态是一个简单的可赋值对象  return new_state  def apply_action(self, action):  GameAPI.apply_action(action)  self.state = GameAPI.get_game_state()  def get_reward(self):  return GameAPI.get_reward()  def simulate(node):  while not node.game_state.is_terminal():  action = random.choice(node.game_state.get_available_actions())  node.game_state.apply_action(action)  return node.game_state.get_reward()  def backpropagate(node, result):  while node:  node.update(result)  node = node.parent  def mcts(root, num_iterations):  for _ in range(num_iterations):  node = root  while node.untried_actions == [] and node.children != []:  node = node.select_child()  if node.untried_actions != []:  node = node.expand()  result = simulate(node)  backpropagate(node, result)  # 示例用法  
game_state = GameState()  
root = Node(game_state)  
num_iterations = 1000  
mcts(root, num_iterations)  
best_child = max(root.children, key=lambda child: child.visits)  
print("推荐动作:", best_child.action)  
print("访问次数:", best_child.visits)

使用这个模拟的GameAPI类,你可以运行之前定义的MCTS算法,并根据模拟的游戏状态来选择最佳动作。

但是在实际应用中,你需要将GameAPI类中的方法实现为与你的FPS游戏API进行交互的代码。

通过以上3个实例,可以对MCTS算法有一点了解了吧,去实现写代码吧~~~~

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

孟德尔随机化--代谢生活方式与消化道癌

写在前面 今天阅读的文献是多种暴露与某结局的孟德尔随机化&#xff0c;算是以量取胜了。 The effect of metabolism-related lifestyle and clinical risk factors on digestive system cancers in East Asian populations: a two-sample Mendelian randomization analysis …

使用tkinter拖入excel文件并显示

使用tkinter拖入excel文件并显示 效果代码 效果 代码 import tkinter as tk from tkinter import ttk from tkinterdnd2 import TkinterDnD, DND_FILES import pandas as pdclass ExcelViewerApp(TkinterDnD.Tk):def __init__(self):super().__init__()self.title("Excel…

谷歌摸鱼神器来了:推出AI会议替身,一键总结提问发言_会议预约 ai对话

饱受会议折磨的打工人&#xff0c;终于可以解放了&#xff01; 就在刚刚举办的Google Cloud Next’23大会上&#xff0c;谷歌宣布了一系列科技新进展&#xff0c;最瞩目的要属其中的“开会AI替身”了。 只需要一句“帮我参加”&#xff0c;AI就能替你开会&#xff0c;并在合适…

设计模式探索:装饰器模式

1. 装饰器模式定义 装饰器模式&#xff08;Decorator Pattern&#xff09; 装饰器模式是一种结构型设计模式&#xff0c;允许向一个对象动态添加行为。在不改变类的接口的情况下&#xff0c;装饰器模式在原始类上增加额外的职责&#xff0c;并且支持多个装饰器嵌套使用。 装…

车载聚合路由器应用场景分析

乾元通QYT-X1z车载式1U多卡聚合路由器&#xff0c;支持最多8路聚合&#xff0c;无论是应急救援&#xff0c;还是车载交通&#xff0c;任何宽带服务商无法覆盖的区域&#xff0c;聚合路由器可提供现场需要的稳定、流畅、安全的视频传输网络&#xff0c;聚合路由器可无缝接入应急…

安装nodejs | npm报错

nodejs安装步骤: 官网&#xff1a;https://nodejs.org/en/ 在官网下载nodejs: 双击下载下来的msi安装包&#xff0c;一直点next&#xff0c;我选的安装目录是默认的: 测试是否安装成功&#xff1a; 输入cmd打开命令提示符&#xff0c;输入node -v可以看到版本&#xff0c;说…

idea创建dynamic web project

由于网课老师用的是eclipse,所以又得自己找教程了…… 解决方案&#xff1a; https://blog.csdn.net/Awt_FuDongLai/article/details/115523552

有没有适合全体质猫咪的主食冻干?全价冻干:希喂大橙罐实测分享

作为一个注重猫咪身体健康和幸福感的铲屎官&#xff0c;怎么会不喂主食冻干。毕竟&#xff0c;除了猫咪爱吃外&#xff0c;高含肉量、高营养的主食冻干也能给猫咪的健康带来一系列的好处。 最近&#xff0c;我给我家猫猫们入手了一款性价比超高的主食冻干&#xff1a;希喂CPMR2…

mybatis中的标签

在MyBatis中&#xff0c;除了基本的SQL映射功能外&#xff0c;还有许多用于动态SQL构建的标签。这些标签允许我们根据不同的条件和需求构建复杂的SQL语句。主要的动态SQL标签包括<if>, <choose>, <when>, <otherwise>, <trim>, <set>, <…

deepstream段错误

&#x1f610; 错误&#xff1a; 探针中由于使用了pyds.get_nvds_buf_surface(hash(gst_buffer), frame_meta.batch_id)导致的段错误&#xff08;segmentation fault&#xff09;。 解决方式&#xff1a;

彩带插画:成都亚恒丰创教育科技有限公司

彩带插画&#xff1a;色彩斑斓的艺术世界 在浩瀚的艺术海洋中&#xff0c;彩带插画以其独特的魅力&#xff0c;如同一条绚烂的彩绸&#xff0c;轻轻拂过人们的心田&#xff0c;留下一抹抹难以忘怀的色彩。成都亚恒丰创教育科技有限公司它不仅仅是一种视觉上的享受&#xff0c;…

二叉树超详细解析

二叉树 目录 二叉树一级目录二级目录三级目录 1.树的介绍1.1树的定义1.2树的基本术语1.3相关性质 2.二叉树介绍2.1定义2.2 性质 3.二叉树的种类3.1 满二叉树3.2完全二叉树3.3 二叉查找树特点&#xff1a;二叉查找树的节点包含的基本信息&#xff1a; 3.4 平衡二叉树 4.二叉树的…

python破解密码·筛查和选择

破解密码时可能遇到的几种情况 ① 已知密码字符&#xff0c;破排序 ② 已知密码位数&#xff0c;破字符 ③ 已知密码类型&#xff0c;破字位 ④ 已知部分密码&#xff0c;破未知 ⑤ 啥都不知道&#xff0c;盲破&#xff0c;玩完 ⑥ 已知位数、字符、类型、部分密码中的几个&am…

单链表(C语言详细版)

1. 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表的结构跟火车车厢相似&#xff0c;淡季时车次的车厢会相应减少&#xff0c;旺季时车次的车厢会额外增加几节。…

资料分析笔记整理

提升技巧多做题、少动笔、多分析 资料分析认识 国考一般20题(24~28分钟) 统计材料的类型包括单纯的文字、表格、图形以及由这些元素组成的复合类型材料 文字性材料:(30~60秒) 多段落型文字材料(时间、关键词、结构) 孤立段落文字材料(时间、关键词、标点[。;]) 表…

VMware vSAN替换存储解决方案如何选择?

What is vSAN &#xff1f; 是一款软件定义的企业存储解决方案&#xff0c;支持超融合基础架构系统。vSAN与VMware vSphere 完全集成在一起&#xff0c;作为ESXi Hypervisor内的分布式软件层&#xff0c;通过整合、池化ESXi各个主机上的存储资源&#xff0c;为vSphere虚拟化平…

施罗德数列SQL实现

在组合数学中,施罗德数用来描述从(0,0)到(n,n)的格路中,只能使用(1,0)、(0,1)、(1,1)三种移动方式,始终位于对角线下方且不越过对角线的路径数 DECLARE n INT 10 DECLARE i INT DECLARE rst INT DECLARE old INT1CREATE TABLE #rst (i INT ,rst int )INSERT INTO #rst values(…

数据结构双向循环链表

主程序 #include "fun.h" int main(int argc, const char *argv[]) { double_p Hcreate_head(); insert_head(H,10); insert_head(H,20); insert_head(H,30); insert_head(H,40); insert_tail(H,50); show_link(H); del_tail(H); …

UE5.3-基础蓝图类整理一

常用蓝图类整理&#xff1a; 1、获取当前关卡名&#xff1a;Get Current LevelName 2、通过关卡名打开关卡&#xff1a;Open Level(by name) 3、碰撞检测事件&#xff1a;Event ActorBeginOverlap 4、获取当前player&#xff1a;Get Player Pawn 5、判断是否相等&#xff1…

回溯算法-以学生就业管理系统为例

1.回溯算法介绍 1.来源 回溯算法也叫试探法&#xff0c;它是一种系统地搜索问题的解的方法。 用回溯算法解决问题的一般步骤&#xff1a; 1、 针对所给问题&#xff0c;定义问题的解空间&#xff0c;它至少包含问题的一个&#xff08;最优&#xff09;解。 2 、确定易于搜…