2018年4月7日 星期六

把超音鼠遊戲導入到 Gym Retro


安裝好 Gym Retro,下一步便是加入遊戲。在得到遊戲後,在 ROM 檔案的目錄中輸入指令「sudo python3 -m retro.import .」把遊戲加入到 Gym Retro 卻不成功。追查加入的程式,它會搜尋 /usr/local/lib/python3.6/site-packages/retro/data/ 內各個遊戲設定的 SHA1 值,如果載入的 ROM 的 SHA1 相同才會進入導入。Gym Retro 支援「SonicTheHedgehog-Genesis」的 SHA1 值是「69e102855d4389c3fd1a8f3dc7d193f8eee5fe5b」,跟手上那個 ROM 的 SHA1 值不同,因此沒有導入。

既然知道原理,只要把 Gym Retro 內關於「SonicTheHedgehog-Genesis」的 SHA1 值修改成手上的 SHA1 值,便能順利導入。於是我參考了 /usr/local/lib/python3.6/site-packages/retro/data.py 編寫了以下 Python 程序:
##--------------------------------------------------------------------
##  Get SHA1 Value of ROM File for Gym Retro
##--------------------------------------------------------------------
##  Platform: macOS High Sierra + Python 3.6
##  Written by Pacess HO
##  Copyright Pacess Studio, 2018.  All rights reserved.
##--------------------------------------------------------------------

import hashlib

##--------------------------------------------------------------------
def parse_smd(header, body):
 import numpy as np
 try:
  if body[0x80] != b'E' or body[0x81] != b'A':
   return header + body
  body2 = b''
  for i in range(len(body) / 0x4000):
   block = body[i * 0x4000:(i + 1) * 0x4000]
   if not block:
    break
   nb = np.fromstring(block, dtype=np.uint8)
   nb = np.flipud(nb.reshape(2, 0x2000))
   nb = nb.flatten(order='F')
   body2 += nb.tostring()
 except IndexError:
  return header + body
 return body2

##--------------------------------------------------------------------
##  Read ROM file
romFile = 'SonicTheHedgehog-Genesis.md'
with open(romFile, 'rb') as r:
 header = r.read(512)
 body = r.read()

##--------------------------------------------------------------------
##  Calculate SHA1
##  * Sonic 1 = c9dceee00a3d24c5460bdd7cd8c45e2f6d02c9fb
##  * Sonic 2 = 14dd06fc3aa19a59a818ea1f6de150c9061b14d4
body = parse_smd(header, body)
header = b''
hashlib.sha1(body).hexdigest()

得到「c9dceee00a3d24c5460bdd7cd8c45e2f6d02c9fb」這個 SHA1 值。把它更新到 /usr/local/lib/python3.6/site-packages/retro/data/SonicTheHedgehog-Genesis/rom.sha 再重新以「sudo python3 -m retro.import .」指令導入,成功了!其實簡簡單單把 ROM 檔案改名做 rom.md 然後放到遊戲目錄都可能會成功... ^_^

要在 Python3 中執行把超音鼠遊戲,輸入以下程序:
import retro

env = retro.make(game='SonicTheHedgehog-Genesis', state='GreenHillZone.Act1')
env.reset()
_obs, _rew, done, _info = env.step(env.action_space.sample())
env.render()

1 則留言:

Unknown 提到...

你好!很激动看到您的教程!我将下载的rom成功添加到reto的已存在游戏目录中,但提示TypeError: filename must be a str or bytes object,or a file!难道是读取数据的方式有误!希望指定下谢谢!(*^__^*)