【星际争霸2中的强化学习-1】使用 PySC2 构建虫族机器人
中文网站上关于星际争霸2中AI模型的训练资料非常少,这里找到一篇比较好的pysc2使用的文章,翻译一下,方便阅读。
代码:GitHub - skjb/pysc2-tutorial: Tutorials for building a PySC2 botTutorials for building a PySC2 bot. Contribute to skjb/pysc2-tutorial development by creating an account on GitHub.https://hub.fastgit.org/skjb/pysc2-tutorial
在本教程中,您将构建一个基本的 Zerg 机器人,该机器人将能够生产 Zergling 并将它们发送到地图上攻击敌人。我假设您具有基本的 Python 编程知识并且能够安装 PySC2 2.0(现在已经是3.0了)。
让我们开始吧。
1. 创建基本代理
首先,让我们导入基本模块:
from pysc2.agents import base_agent
from pysc2.env import sc2_env
from pysc2.lib import actions, features
from absl import app
现在我们可以创建我们的代理:
class ZergAgent(base_agent.BaseAgent):def step(self, obs):super(ZergAgent, self).step(obs)return actions.FUNCTIONS.no_op()
该step
方法是我们代理的核心部分,它是我们所有的决策发生。在每一步结束时,你必须返回一个动作,在这种情况下,动作是什么都不做。我们将很快添加更多操作。
如果您遵循我之前的教程,您会注意到操作的格式已更改,以前最后一行是:
return actions.FunctionCall(actions.FUNCTIONS.no_op.id, [])
我认为新格式更简单,更容易遵循,蒂莫在这里做得很好。
2. 添加运行代码
现在我们设置环境,以便我们可以运行它。在我的原始教程中,我们在命令行上运行代理并传递了许多参数,但在这里我们将添加一些代码以使其能够在没有这些额外参数的情况下运行代理。
def main(unused_argv):agent = ZergAgent()try:while True:with sc2_env.SC2Env(map_name="AbyssalReef",
我在这里选择使用深海礁地图,它比我之前教程中的简单 64 地图更有趣。
players=[sc2_env.Agent(sc2_env.Race.zerg),
这里我们指定第一个玩家是我们的代理,代理的种族是虫族。您只需使用sc2_env.Race.protoss
,sc2_env.Race.terran
或者即使sc2_env.Race.random
您很勇敢,也可以选择另一个种族。
sc2_env.Bot(sc2_env.Race.random,sc2_env.Difficulty.very_easy)],
接下来我们指定第二个玩家是机器人,这意味着它使用了游戏的内部 AI,机器人的种族是随机的,并且难度级别非常简单。可能的难度水平very_easy
,easy
,medium
,medium_hard
,hard
,harder
,very_hard
,cheat_vision
,cheat_money
和cheat_insane
。请注意,medium_hard
在游戏中实际上hard
是“困难”、“更难”、harder
“非常困难”和very_hard
“精英”。
在此空间中,您可以选择指定另一个代理,允许两个代理相互对战!
agent_interface_format=features.AgentInterfaceFormat(feature_dimensions=features.Dimensions(screen=84, minimap=64)),
在这里我们指定屏幕和小地图分辨率,这些是 PySC2 1.x 中的默认值。这些分辨率本质上决定了每个要素图层中有多少“像素”数据,这些图层包括地形高度、可见性和单位所有权等内容。您的机器人可以使用这些功能来做出决策。
PySC2 2.0 中的新功能之一是添加了 RGB 层,本质上是人类会看到的渲染游戏,如果您想使用该层,则需要在此处将尺寸指定为rgb_dimensions
,但我们不会介绍在本教程中。
step_mul=16,
此参数确定在您的机器人选择要执行的操作之前经过多少“游戏步骤”。默认设置为 8,在“正常”游戏速度下大约为 300 APM,我们将其设置为 160 以将 APM 降低到 150。在此阶段不需要额外的 APM,游戏将更快完成如果你少采取行动。
game_steps_per_episode=0,
这里我们设置了每场比赛的固定长度,PySC2 1.x 中的默认值在正常速度下约为 30 分钟。在 PySC2 2.0 中,您可以将此值设置为 0 以允许游戏根据需要运行。
visualize=True) as env:
最后一个参数是可选的,但是您可以方便地查看可视化,因为它包含有关您的机器人可用的所有观察层的详细信息。通过查看屏幕上呈现的这些层,您可以更好地理解它们。
agent.setup(env.observation_spec(), env.action_spec())timesteps = env.reset()agent.reset()while True:step_actions = [agent.step(timesteps[0])]if timesteps[0].last():breaktimesteps = env.step(step_actions)except KeyboardInterrupt:passif __name__ == "__main__":app.run(main)
其余的代码只是关于循环、将步骤详细信息提供给代理、接收动作并重复直到游戏结束或直到游戏终止。
现在您可以运行您的代理:
python zerg_agent.py
您应该看到您的特工收集矿物,直到它最终被敌人占领。
3. 选择无人机
在 Zerg 代理可以生产任何 Zergling 之前,它需要一个产卵池。为了建立一个产卵池,我们需要选择一个无人机,所以让我们这样做。 PySC2 2.0 的一项很酷的新功能是添加了功能单元。我知道这个功能很酷,因为我做到了。它允许您通过屏幕要素图层获取有关屏幕上您无法观察或可能更困难的单位的信息。我们将使用特征单元来选择无人机。 另一个很酷的新功能之一是添加了一个单位列表,它允许您使用单位名称检索单位类型。以前我们用类似的东西编码我们自己的单位类型,_TERRAN_SCV = 45但现在我们可以使用类似的东西units.Terran.SCV。我也做了这个功能:) 让我们将单元列表添加到模块导入中:
from pysc2.lib import actions, features, units
import random
我们还需要这个random
模块来做一些事情。
接下来我们需要启用特征单元:
agent_interface_format=features.AgentInterfaceFormat(feature_dimensions=features.Dimensions(screen=84, minimap=64),use_feature_units=True),
现在,在该step()
方法中,让我们使用特征单元功能来获取屏幕上所有无人机的列表:
def step(self, obs):super(ZergAgent, self).step(obs)drones = [unit for unit in obs.observation.feature_unitsif unit.unit_type == units.Zerg.Drone]
这很酷,对吧?!多亏了新的点符号,一切看起来都更干净了,谢谢 Timo!以前你可能做过类似的事情:
unit_type = obs.observation["screen"][features.SCREEN_FEATURES.unit_type.index]
unit_y, unit_x = (unit_type == 104).nonzero()
现在,让我们选择一个无人机:
if len(drones) > 0:drone = random.choice(drones)return actions.FUNCTIONS.select_point("select_all_type", (drone.x,drone.y))
select_all_type
此处的参数就像 CTRL+单击,因此将选择屏幕上的所有无人机。如您所见,无人机的x和y坐标可作为属性访问。还有更多的属性,你可以访问,如health
,shields
,energy
,build_progress
,重要的ideal_harvesters
和assigned_harvesters
对基地和vespene。
如果您愿意,您现在可以运行代理,以确保您的无人机被选中。
4. 建立一个产卵池
def unit_type_is_selected(self, obs, unit_type):if (len(obs.observation.single_select) > 0 andobs.observation.single_select[0].unit_type == unit_type):return Trueif (len(obs.observation.multi_select) > 0 andobs.observation.multi_select[0].unit_type == unit_type):return Truereturn False
此代码检查单选和多选以查看第一个选择的单位是否是正确的类型。在顶部,step()
我们可以将此方法用于:
def step(self, obs):super(ZergAgent, self).step(obs)if self.unit_type_is_selected(obs, units.Zerg.Drone):
接下来我们要确保我们可以构建一个产卵池。如果我们没有足够的矿物质,这可能是不可能的,如果我们不先检查,就会导致崩溃:
if (actions.FUNCTIONS.Build_SpawningPool_screen.id in obs.observation.available_actions):
然后我们可以在屏幕上随机选择一个点,希望在一些蠕变:
x = random.randint(0, 83)y = random.randint(0, 83)return actions.FUNCTIONS.Build_SpawningPool_screen("now", (x, y))
最后,我们将随机坐标输入到动作中。
试一试,看看效果如何。运气好的话,您将拥有大量的产卵池。我们如何阻止我们所有的无人机成为产卵池?
让我们添加另一种实用方法来选择具有给定单位类型的单位:
def get_units_by_type(self, obs, unit_type):return [unit for unit in obs.observation.feature_unitsif unit.unit_type == unit_type]
这与您上面的代码相同,但unit_type
可以根据需要换出。让我们用方法来替换之前的代码:
drones = self.get_units_by_type(obs, units.Zerg.Drone)
然后我们可以使用该方法来获取产卵池:
spawning_pools = self.get_units_by_type(obs, units.Zerg.SpawningPool)if len(spawning_pools) == 0:if self.unit_type_is_selected(obs, units.Zerg.Drone):if (actions.FUNCTIONS.Build_SpawningPool_screen.id in obs.observation.available_actions):x = random.randint(0, 83)y = random.randint(0, 83)return actions.FUNCTIONS.Build_SpawningPool_screen("now", (x, y))drones = self.get_units_by_type(obs, units.Zerg.Drone)if len(drones) > 0:drone = random.choice(drones)return actions.FUNCTIONS.select_point("select_all_type", (drone.x,drone.y))
那就更好了,如果我们还没有一个产卵池,我们现在只会建造一个产卵池。
5. 建立跳虫
差不多好了!现在我们有了一个产卵池,我们终于可以建造一些跳虫了。让我们从选择屏幕上的所有幼虫开始:
larvae = self.get_units_by_type(obs, units.Zerg.Larva)if len(larvae) > 0:larva = random.choice(larvae)return actions.FUNCTIONS.select_point("select_all_type", (larva.x,larva.y))
然后我们可以创建一些跳虫。将此代码放在上一个块的正上方:
if self.unit_type_is_selected(obs, units.Zerg.Larva):if (actions.FUNCTIONS.Train_Zergling_quick.id in obs.observation.available_actions):return actions.FUNCTIONS.Train_Zergling_quick("now")
给它一个测试,你应该得到一对跳虫。
这很好,但我们无法建造足够多的跳虫来发挥作用,我们的供应有限。我们需要霸主。
6. 产生更多的霸主
当我们选择了幼虫,如果我们没有免费供应,我们可以产生一个霸王:
free_supply = (obs.observation.player.food_cap -obs.observation.player.food_used)if free_supply == 0:if (actions.FUNCTIONS.Train_Overlord_quick.id inobs.observation.available_actions):return actions.FUNCTIONS.Train_Overlord_quick("now")
最后一件事我不喜欢,让我们添加另一种方法:
def can_do(self, obs, action):return action in obs.observation.available_actions
我们现在可以替换动作检查:
if self.can_do(obs, actions.FUNCTIONS.Build_SpawningPool_screen.id):
和:
if self.can_do(obs, actions.FUNCTIONS.Train_Zergling_quick.id):
和:
if self.can_do(obs, actions.FUNCTIONS.Train_Overlord_quick.id):
如果你现在测试你的机器人,你会发现它会产生很多跳虫,是时候攻击了!
7. 攻击
在我们进攻之前,我们需要知道我们在哪里,敌人在哪里。出于本教程的目的,我们将假设生成位置始终位于左上角和右下角。所以我们需要找出我们在哪里,然后攻击对方。 让我们创建一个__init__()方法来初始化一个变量:
def __init__(self):super(ZergAgent, self).__init__()self.attack_coordinates = None
在step()
方法的开头,添加以下内容:
def step(self, obs):super(ZergAgent, self).step(obs)if obs.first():player_y, player_x = (obs.observation.feature_minimap.player_relative ==features.PlayerRelative.SELF).nonzero()xmean = player_x.mean()ymean = player_y.mean()if xmean <= 31 and ymean <= 31:self.attack_coordinates = (49, 49)else:self.attack_coordinates = (12, 16)
该obs.first()
代码检查它是否是游戏的第一步。然后我们在小地图上获得我们单位的中心x和y坐标。有一个功能层可以根据它们所属的人在小地图上显示所有单位。我将在以后的教程中更详细地解释这一点。
现在我们有了我们的攻击位置,让我们开始攻击。首先我们选择我们的军队:
zerglings = self.get_units_by_type(obs, units.Zerg.Zergling)if len(zerglings) > 0:if self.can_do(obs, actions.FUNCTIONS.select_army.id):return actions.FUNCTIONS.select_army("select")
在此之前,我们可以攻击:
if len(zerglings) > 0:if self.unit_type_is_selected(obs, units.Zerg.Zergling):if self.can_do(obs, actions.FUNCTIONS.Attack_minimap.id):return actions.FUNCTIONS.Attack_minimap("now",self.attack_coordinates)
测试一下。该死,我们的小狗被咬了!让我们等到我们有更多的跳虫后再进攻:
if len(zerglings) >= 10:
效果好多了~
【星际争霸2中的强化学习-1】使用 PySC2 构建虫族机器人相关推荐
- 强化学习(六) - 连续空间中的强化学习(RL in Continuous Spaces)及相关实例
强化学习(六) - 连续空间中的强化学习 6.1 连续空间中的强化学习 6.2 离散空间和连续空间 6.3 离散化 实例:小车上山 6.3.1 相关程序 6.3.2 程序注解 (1) 环境测试 (2) ...
- 游戏中应用强化学习技术,目的就是要打败人类玩家?
来源:AI前线 作者:凌敏 采访嘉宾:黄鸿波 2016 年,DeepMind 公司开发的 AlphaGo 4:1 大胜韩国著名棋手李世石,成为第一个战胜围棋世界冠军的人工智能机器人,一时风头无两.Al ...
- 在Unity环境中使用强化学习训练Donkey Car(转译)
在Unity环境中使用强化学习训练Donkey Car 1.Introduction 简介 2. Train Donkey Car with Reinforcement Learning 使用强化学习 ...
- 【强化学习-医疗】医疗保健中的强化学习:综述
Article 作者:Chao Yu, Jiming Liu, Shamim Nemati 文献题目:医疗保健中的强化学习:综述 文献时间:2020 文献链接:https://arxiv.org/ab ...
- 在星际争霸II中测试几个按键屏显软件的效果
虽然暴雪卖身微软,但其开发的游戏还是不错的.比如星际争霸II,已经可以暴雪战网(战网 )免费玩了. 要成为游戏高手,对键盘操作一定要熟练,星际争霸对战高手对键盘操作都是很溜的.低手经常要低头看键盘, ...
- 走向开放世界强化学习、IJCAI2022论文精选、机器人 RL 工具、强化学习招聘、《强化学习周刊》第73期...
No.73 智源社区 强化学习组 强 化 学 习 周刊订阅 <强化学习周刊>已经开启"订阅功能",扫描下面二维码,进入主页,选择"关注TA",我们 ...
- Google DeepMind顾问预言:五年后AI将在《星际争霸》中战胜人类
在纽芬兰和拉布拉多,正在用人工智能进行<星际争霸>比赛. <星际争霸>的幽灵机器人.(来自:维基共享资源) 接下来的两个星期里,在纪念大学(Memorial Universit ...
- 今晚直播 |现实环境中的强化学习如何解决?你不可错过的RL终极奥义
都说强化学习很难,其实掌握了正确的学习方法,也会变得非常简单! 这次,所以我们荣幸的邀请到了百度连续两届获得NeurIPS全球顶会赛事冠军团队,6月16日-6月23日,连续7天,20:30-21:30 ...
- chatgpt中的强化学习 PPO
PPO? 强化学习 基本概念 强化学习五要素:智能体.行为.环境.状态.奖励. 先直接将五个要素映射到文本生成任务上: 智能体:生成模型. 行为: 获取当前step token的概率分布,并选取其中一 ...
最新文章
- yolov5 v3.0训练报错: torch.nn.modules.module.ModuleAttributeError: ‘BatchNorm2d‘ object has no attribute
- Java怎么学?在学Java的过程中要注意些什么呢?
- Mvc过滤器的使用【转载】
- 做算法,为什么建议你一定要学懂C++?
- 10分钟学会python函数式编程,赶紧收藏!!
- vs生成命令和属性的宏
- MyCAT实现MySQL的读写分离
- java list 过滤数据库_jdk8对list的各种处理实例详解,包括去重,排序,过滤,分组,统计...
- 基于stc15f2k60s2芯片单片机编程(按键的长短按)
- 网易云音乐数仓模型设计实践
- unix下c语言recv函数,Linux send与recv函数详解
- 掠过和记黄埔IDC机房
- 苹果 macOS「搜狗拼音输入法」自定义双拼方案的教程
- 苹果手机怎么验证app_苹果序列号查询 未验证怎么办?
- JAVA小游戏黄金矿工
- [XJTUSE 算法设计与分析] 第五章 回溯法
- eslint报“Extra semicolon“错误的解决
- Azure 上通过 SendGrid 发送邮件
- Twin Builder—系统级多物理域数字孪生平台
- 分布式之Quorum NWR算法