OpenAI Retro Contestの環境でリプレイ映像を見る

OpenAI Retro Contestの環境構築そのものは既にまとめてくれている方がいて、大変わかりやすかった。この通りにやったら簡単にGym Retro Integrationを動かすことができた。ありがとうございます。

OpenAI Retro Contestの「Gym Retro Integration」でソニック・ザ・ヘッジホッグをプレイする - おおかみ山

ここで作った環境でagentのアルゴリズムを書いていろいろ試すわけだが、その前に動かした結果を確認する方法が必要なので、リプレイを確認する方法をメモしておく。

まずcontestの公式イントロダクションはこちら

https://contest.openai.com/details

こちらに則ってretro_contest.localというwrapperを使ってひとまず動かしてみる。 以下でretro-contestを入れる。

git clone --recursive https://github.com/openai/retro-contest.git
pip install -e "retro-contest/support[docker,rest]"

常に右に動き続けるagentで記録を取る(ランダムだとその場からなかなか進まなくてゲームが終わらないので)

# sonic_simple.py

from retro_contest.local import make

def main():
    env = make(game='SonicTheHedgehog-Genesis', state='LabyrinthZone.Act1', bk2dir='./data')
    obs = env.reset()
    while True:
        action = env.action_space.sample()
        action[7] = 1
        obs, rew, done, info = env.step(action)
        env.render()
        if done:
            break

    env.close()

if __name__ == '__main__':
    main()

makeの第3引数でbk2dirを設定することで、実行時に指定したディレクトリ内に.bk2というバイナリファイルが作成される。

$ mkdir data
$ python sonic_simple.py
$ ls data
SonicTheHedgehog-Genesis-LabyrinthZone-000000.bk2

openai/retroのreadmeにこれをmp4にする方法が書かれている

GitHub - openai/retro: Retro Games in Gym

mp4に変換したいなら以下のスクリプトを使えばOK。

retro/playback_movie.py at master · openai/retro · GitHub

$ git clone https://github.com/openai/retro.git
$ python retro/scripts/playback_movie.py data/SonicTheHedgehog-Genesis-LabyrinthZone-000000.bk2
...いろいろ出力...
$ ls data
SonicTheHedgehog-Genesis-LabyrinthZone-000000.bk2 SonicTheHedgehog-Genesis-LabyrinthZone-000000.mp4

mp4にする必要なくリプレイを見たいだけの場合は以下のスクリプトを実行すれば、学習時と同じ形のウィンドウでリプレイが見られる(再生速度も速い)

# playback.py

import argparse
import sys
import retro

def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser(add_help=True)
    parser.add_argument('path', help='path to .bk2 file')
    args = parser.parse_args(argv)

    movie = retro.Movie(args.path)
    movie.step()

    env = retro.make(game=movie.get_game(), use_restricted_actions=retro.ACTIONS_ALL)
    env.initial_state = movie.get_state()
    env.reset()

    while movie.step():
        keys = []
        for i in range(env.NUM_BUTTONS):
            keys.append(movie.get_key(i))
        env.render()
        _obs, _rew, _done, _info = env.step(keys)

if __name__ == '__main__':
    main()

実行

$ python playback.py SonicTheHedgehog-Genesis-LabyrinthZone-000000.bk2