linyiLYi / street-fighter-ai

This is an AI agent for Street Fighter II Champion Edition.
Apache License 2.0
6.3k stars 1.36k forks source link

最后林哥是如何搞定生成最后一关存档文件的? #31

Open tonyxu99 opened 1 year ago

tonyxu99 commented 1 year ago

看了你的GPT对话,GTP一直都没有给出有效方法。林哥最后说他自己搞定了。请问林哥是如何搞定的? 我自己修改了一下代码,让可以2P模式并支持键盘。我希望自己可以操作角色对战训练好的AI。可惜现有的存档都是1P的。我尝试按2P的“START”按钮,也没办法加入2P对战(可能没放币)。 所以应该只有两张方法:

  1. 用其他模拟器玩游戏,并进入2P对战,然后存档。只是根据GPT对话,没有找到合适的其他模拟器。
  2. 用键盘自己玩GymRetro,并进入2P对战,然后存档。我修改的代码可以用键盘玩,但不知如何投币。
Datou commented 1 year ago

“gym-retro 可以另下一个可执行程序,是一个模拟器,放在 gym-retro 文件夹下可以运行,用这个模拟器就能保存 .state 文件了” 林哥如是说

tonyxu99 commented 1 year ago

多谢。我会试一试那个Integration UI. 另外我知道为什么“Start”按钮不工作了,原来默认屏蔽“Start”按钮(可能防止AI乱按“Start”按钮)。要修改scenario.json激活“Start”按钮。

tonyxu99 commented 1 year ago

那个Integration UI不知为何无法运行游戏。最后我还是在Retro中用以下方法保存State。现在我已经可以用键盘和林哥训练的AI对打了。老实说,这个AI还是无法和真人匹敌的。

def save_state_to_file(env, name="test.state"): content = env.em.get_state() with gzip.open(name, 'wb') as f: f.write(content)

https://stackoverflow.com/questions/66890733/how-to-save-gamestate-objects-in-python

Datou commented 1 year ago

那个Integration UI不知为何无法运行游戏。最后我还是在Retro中用以下方法保存State。现在我已经可以用键盘和林哥训练的AI对打了。老实说,这个AI还是无法和真人匹敌的。

def save_state_to_file(env, name="test.state"): content = env.em.get_state() with gzip.open(name, 'wb') as f: f.write(content)

https://stackoverflow.com/questions/66890733/how-to-save-gamestate-objects-in-python

可以提供一下和AI对打的方法吗?另外是不是可以用对战的方式把训练从对战电脑变成AI之间的自我对战?

tonyxu99 commented 1 year ago

可以提供一下和AI对打的方法吗?--有时间我可以建个repo把我的code上传。 另外是不是可以用对战的方式把训练从对战电脑变成AI之间的自我对战?--应该可以吧?我也很有兴趣试一试。

tonyxu99 commented 1 year ago

我已经上传了和AI对打的代码:https://github.com/tonyxu99/String_fighter_AI

qjchen1972 commented 1 year ago

我已经上传了和AI对打的代码:https://github.com/tonyxu99/String_fighter_AI

多谢。我会试一试那个Integration UI. 另外我知道为什么“Start”按钮不工作了,原来默认屏蔽“Start”按钮(可能防止AI乱按“Start”按钮)。要修改scenario.json激活“Start”按钮。

怎么修改scenario.json激活“Start”按钮?

tonyxu99 commented 1 year ago

我已经上传了和AI对打的代码:https://github.com/tonyxu99/String_fighter_AI

多谢。我会试一试那个Integration UI. 另外我知道为什么“Start”按钮不工作了,原来默认屏蔽“Start”按钮(可能防止AI乱按“Start”按钮)。要修改scenario.json激活“Start”按钮。

怎么修改scenario.json激活“Start”按钮?

加上这段: "actions": [ [[], ["UP"], ["DOWN"]], [[], ["LEFT"], ["RIGHT"]], [[], ["A"], ["B"], ["C"], ["X"], ["Y"], ["Z"], ["A", "B"], ["B", "C"], ["A", "X"], ["B", "Y"], ["C", "Z"], ["X", "Y"], ["Y", "Z"], ["START"]] ], 请注意最后的逗号,不要破坏JSON格式。

qjchen1972 commented 1 year ago

我已经上传了和AI对打的代码:https://github.com/tonyxu99/String_fighter_AI

多谢。我会试一试那个Integration UI. 另外我知道为什么“Start”按钮不工作了,原来默认屏蔽“Start”按钮(可能防止AI乱按“Start”按钮)。要修改scenario.json激活“Start”按钮。

怎么修改scenario.json激活“Start”按钮?

加上这段: "actions": [ [[], ["UP"], ["DOWN"]], [[], ["LEFT"], ["RIGHT"]], [[], ["A"], ["B"], ["C"], ["X"], ["Y"], ["Z"], ["A", "B"], ["B", "C"], ["A", "X"], ["B", "Y"], ["C", "Z"], ["X", "Y"], ["Y", "Z"], ["START"]] ], 请注意最后的逗号,不要破坏JSON格式。

谢谢,一会试试。昨晚在retro的example里的interactivate.py里,把按键扩展到24位,同时设置use_restricted_actions=retro.Actions.ALL,是可以用interactivate.py进行mode设置成2p对战。也参考了你的代码对state进行了保存。

quantumiracle commented 1 year ago

@qjchen1972

谢谢,一会试试。昨晚在retro的example里的interactivate.py里,把按键扩展到24位,同时设置use_restricted_actions=retro.Actions.ALL,是可以用interactivate.py进行mode设置成2p对战。也参考了你的代码对state进行了保存。

你好,可以麻烦说下具体是怎么设置的吗,在interactivate.py下按哪几个键来选择2p模式? 谢谢

qjchen1972 commented 1 year ago

@qjchen1972

谢谢,一会试试。昨晚在retro的example里的interactivate.py里,把按键扩展到24位,同时设置use_restricted_actions=retro.Actions.ALL,是可以用interactivate.py进行mode设置成2p对战。也参考了你的代码对state进行了保存。

你好,可以麻烦说下具体是怎么设置的吗,在interactivate.py下按哪几个键来选择2p模式? 谢谢

对应修改一下retro的example里的interactivate.py:

class RetroInteractive(Interactive): """ Interactive setup for retro games """

def __init__(self, game, state, scenario):       
    env = retro.make(game=game, state=state, scenario=scenario, 
                     use_restricted_actions=retro.Actions.ALL,
                     players=2)                         

    self._buttons = ['B1', 'A1', 'MODE1', 'START1', 'UP1', 'DOWN1', 'LEFT1', 'RIGHT1', 'C1', 'Y1', 'X1', 'Z1']
    self._buttons += ['B2', 'A2', 'MODE2', 'START2', 'UP2', 'DOWN2', 'LEFT2', 'RIGHT2', 'C2', 'Y2', 'X2', 'Z2']
    print("buttons:" , env.buttons)
    super().__init__(env=env, sync=False, tps=60, aspect_ratio=4/3)

def get_image(self, _obs, env):
    return env.render(mode='rgb_array')

def keys_to_act(self, keys):
    inputs = {
        None: False,

        'BUTTON': 'Z' in keys,
        'A1': 'Z' in keys,
        'B1': 'X' in keys,

        'C1': 'C' in keys,
        'X1': 'A' in keys,
        'Y1': 'S' in keys,
        'Z1': 'D' in keys,

        'L1': 'Q' in keys,
        'R1': 'W' in keys,

        'UP1': 'UP' in keys,
        'DOWN1': 'DOWN' in keys,
        'LEFT1': 'LEFT' in keys,
        'RIGHT1': 'RIGHT' in keys,

        'MODE1': 'TAB' in keys,
        'SELECT1': 'TAB' in keys,
        'RESET1': 'ENTER' in keys,
        'START1': 'ENTER' in keys,

        'BUTTON2': 'Z' in keys,
        'A2': 'J' in keys,
        'B2': 'K' in keys,

        'C2': 'L' in keys,
        'X2': 'U' in keys,
        'Y2': 'I' in keys,
        'Z2': 'O' in keys,

        'L2': 'Q' in keys,
        'R2': 'E' in keys,

        'UP2': 'W' in keys,
        'DOWN2': 'S' in keys,
        'LEFT2': 'A' in keys,
        'RIGHT2': 'D' in keys,

        'MODE2': 'M' in keys,
        'SELECT2': 'TAB' in keys,
        'RESET2': 'ENTER' in keys,
        'START2': 'N' in keys,
    }        
    return [inputs[b] for b in self._buttons]

def main(): parser = argparse.ArgumentParser() parser.add_argument('--game', default='Airstriker-Genesis') parser.add_argument('--state', default=retro.State.DEFAULT) parser.add_argument('--scenario', default='scenario') args = parser.parse_args() game = "StreetFighterIISpecialChampionEdition-Genesis" state = retro.State.NONE ia = RetroInteractive(game=game, state=state, scenario=args.scenario)
ia.run()

此时就可以选择2p对战 以及设置stage 和难度了,特别注意的是, 前面12个键是第一个玩家选择,后面12个键是另一个 第一个用enter确认 第二个用 ‘N“

tonyxu99 commented 1 year ago

是的,设置了use_restricted_actions=retro.Actions.ALL, 就不用修改scenario.json。谢谢你的信息。