Python玩街机

2024-04-17 08:08
文章标签 python 街机

本文主要是介绍Python玩街机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

来源:GitHub

编译:Bot

编者按:近年来,虽然关于强化学习进展的新闻屡见报端,对强化学习感兴趣的人也很多,但对普通学习者来说,真正做一个自己感兴趣的强化学习项目还是太麻烦了。今天论智给大家推荐的是一名网友开源的Python库,它提供了一个可以玩任何旧版街机游戏的API,操作方式非常亲民。

640?

这是一个允许你在几乎任何街机游戏中训练你的强化学习算法的Python库,它目前在Linux系统上可用。通过这个工具包,你可以定制算法逐步完成游戏过程,同时接收每一帧的数据和内部存储器地址值以跟踪游戏状态,以及发送与游戏交互的动作。

安装

GitHub地址:github.com/M-J-Murray/MAMEToolkit/blob/master/README.md

你可以用pip安装这个库,只需运行以下命令:

pip install MAMEToolkit

演示示例:街霸

在街机爱好者心中,街霸是史上最经典的游戏之一。现在工具包内包含的街霸版本是街头霸王3:三度冲击(Japan 990608, NO CD),我们以此为例,用以下代码写一个随机智能体:

import random	
from MAMEToolkit.sf_environment import Environment	roms_path = "roms/"	
env = Environment("env1", roms_path)	
env.start()	
while True:	move_action = random.randint(0, 8)	attack_action = random.randint(0, 9)	frames, reward, round_done, stage_done, game_done = env.step(move_action, attack_action)	if game_done:	env.new_game()	elif stage_done:	env.next_stage()	elif round_done:	env.next_round()

这个工具包还支持hogwild!训练:

什么是hogwild!? Niu等人引入了一个叫做 Hogwild! 的更新策略,可以使 SGD 可以在多 CPU 上并行更新。处理器在无需对参数加锁的情况下就可以访问共享内存。但仅在输入的是稀疏数据时才有效,因为每次更新仅修改所有参数的一小部分。他们展示了在这种情况下,更新策略几乎可以达到一个最优的收敛率,因为处理器不太可能覆盖掉有用的信息。

from threading import Thread	
import random	
from MAMEToolkit.sf_environment import Environment	def run_env(env):	env.start()	while True:	move_action = random.randint(0, 8)	attack_action = random.randint(0, 9)	frames, reward, round_done, stage_done, game_done = env.step(move_action, attack_action)	if game_done:	env.new_game()	elif stage_done:	env.next_stage()	elif round_done:	env.next_round()	def main():	workers = 8	# Environments must be created outside of the threads	roms_path = "roms/"	envs = [Environment(f"env{i}", roms_path) for i in range(workers)]	threads = [Thread(target=run_env, args=(envs[i], )) for i in range(workers)]	[thread.start() for thread in threads]

建立自己的游戏环境

这个工具包之所以易于上手,是因为它和模拟器本身不需要太多交互,只需注意两点——一是查找你关注的内部状态相关联的内存地址值,二是用选取的环境跟踪状态。你可以用MAME Cheat Debugger,它会反馈游戏的内存地址值如何随时间变化。如果要创建游戏模拟,你得先获得正在模拟的游戏的ROM,并知道MAME使用的游戏ID,比如街霸的ID是'sfiii3n'。

游戏ID

你可以通过运行以下代码找到游戏的ID:

from MAMEToolkit.emulator import Emulator	
emulator = Emulator("env1", "", "", memory_addresses)

这个命令会打开MAME仿真器。你可以搜索游戏列表以找到想要的游戏,游戏的ID位于游戏标题末尾的括号中。

内存地址

如果获得了ID,也有了想要跟踪的内存地址,你可以开始模拟:

from MAMEToolkit.emulator import Emulator	
from MAMEToolkit.emulator import Address	roms_path = "roms/"	
game_id = "sfiii3n"	
memory_addresses = {	"fighting": Address('0x0200EE44', 'u8'),	"winsP1": Address('0x02011383', 'u8'),	"winsP2": Address('0x02011385', 'u8'),	"healthP1": Address('0x02068D0B', 's8'),	"healthP2": Address('0x020691A3', 's8')	}	emulator = Emulator("env1", roms_path, "sfiii3n", memory_addresses)

这会启动仿真器,并在工具包连接到模拟器进程时暂停。

分步运行仿真器

连接工具箱后,你可以分步运行仿真器:

data = emulator.step([])	frame = data["frame"]	
is_fighting = data["fighting"]	
player1_wins = data["winsP1"]	
player2_wins = data["winsP2"]	
player1_health = data["healthP1"]	
player2_health = data["healthP2"]

step函数会把帧数据作为NumPy矩阵返回,同时,它也会返回该时间步长的所有内存地址整数值。

如果要向仿真器输入动作,你还需要确定游戏支持的输入端口和字段。比如玩街霸需要先投币,这个代码是:

from MAMEToolkit.emulator import Action	insert_coin = Action(':INPUTS', 'Coin 1')	
data = emulator.step([insert_coin])

要确定哪些端口可用,请使用list actions命令:

from MAMEToolkit.emulator import list_actions	roms_path = "roms/"	
game_id = "sfiii3n"	
print(list_actions(roms_path, game_id))

下面这个返回的列表就包含街霸环境中可用于向步骤函数发送动作的所有端口和字段:

[	{'port': ':scsi:1:cdrom:SCSI_ID', 'field': 'SCSI ID'}, 	{'port': ':INPUTS', 'field': 'P2 Jab Punch'}, 	{'port': ':INPUTS', 'field': 'P1 Left'}, 	{'port': ':INPUTS', 'field': 'P2 Fierce Punch'}, 	{'port': ':INPUTS', 'field': 'P1 Down'}, 	{'port': ':INPUTS', 'field': 'P2 Down'}, 	{'port': ':INPUTS', 'field': 'P2 Roundhouse Kick'}, 	{'port': ':INPUTS', 'field': 'P2 Strong Punch'}, 	{'port': ':INPUTS', 'field': 'P1 Strong Punch'}, 	{'port': ':INPUTS', 'field': '2 Players Start'}, 	{'port': ':INPUTS', 'field': 'Coin 1'}, 	{'port': ':INPUTS', 'field': '1 Player Start'}, 	{'port': ':INPUTS', 'field': 'P2 Right'}, 	{'port': ':INPUTS', 'field': 'Service 1'}, 	{'port': ':INPUTS', 'field': 'Coin 2'}, 	{'port': ':INPUTS', 'field': 'P1 Jab Punch'}, 	{'port': ':INPUTS', 'field': 'P2 Up'}, 	{'port': ':INPUTS', 'field': 'P1 Up'}, 	{'port': ':INPUTS', 'field': 'P1 Right'}, 	{'port': ':INPUTS', 'field': 'Service Mode'}, 	{'port': ':INPUTS', 'field': 'P1 Fierce Punch'}, 	{'port': ':INPUTS', 'field': 'P2 Left'}, 	{'port': ':EXTRA', 'field': 'P2 Short Kick'}, 	{'port': ':EXTRA', 'field': 'P2 Forward Kick'}, 	{'port': ':EXTRA', 'field': 'P1 Forward Kick'}, 	{'port': ':EXTRA', 'field': 'P1 Roundhouse Kick'}, 	{'port': ':EXTRA', 'field': 'P1 Short Kick'}	
]

仿真器类还有一个frame_ratio参数,可用于调整算法所见的帧速率。默认情况下,MAME以每秒60帧的速度生成帧,如果你觉得这太多了,想把它改成每秒20帧,可以输入以下代码:

from MAMEToolkit.emulator import Emulator	emulator = Emulator(roms_path, game_id, memory_addresses, frame_ratio=3)

MAME性能基准测试

目前这个工具包的开发和测试已在8核AMD FX-8300 3.3GHz CPU以及3GB GeForce GTX 1060 GPU上完成。在使用单个随机智能体的情况下,街头霸王环境可以以正常游戏速度的600%+运行。而如果是用8个随机智能体进行hogwild!训练,环境可以以正常游戏速度的300%+运行。

ConvNet智能体

为了确保工具包能够训练算法,作者还设置了一个简单的5层ConvNet,只需少量调整,你就可以用它进行测试。在街霸实验中,这个算法能够成功学习到游戏的一些简单技巧,比如连击(combo)和格挡(blocking)。街霸本身的游戏机制是分成10个关卡(难度递增),玩家在每个关卡都要迎战不同的对手。刚开始的时候,这个智能体平均只能打到第2关。但在经过2200次训练后,它平均能打到第5关。

至于智能体的学习率,它是用每一局智能体所造成的净伤害和所承受的伤害来计算的。

640?

640?wx_fmt=gif

Pls Follow It!

这篇关于Python玩街机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/911247

相关文章

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

python常用的正则表达式及作用

《python常用的正则表达式及作用》正则表达式是处理字符串的强大工具,Python通过re模块提供正则表达式支持,本文给大家介绍python常用的正则表达式及作用详解,感兴趣的朋友跟随小编一起看看吧... 目录python常用正则表达式及作用基本匹配模式常用正则表达式示例常用量词边界匹配分组和捕获常用re

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图