예제 #1
0
def loadCartridge(filePath, quiet=True, emSpd=1):
    pyboy = PyBoy(filePath,
                  window_type="headless" if quiet else "SDL2",
                  window_scale=3,
                  debug=not quiet,
                  game_wrapper=True)
    pyboy.set_emulation_speed(emSpd)
    pyboy.cartridge_title() == "SUPER MARIOLAN"
    return pyboy
예제 #2
0
def test_mario_basics():
    pyboy = PyBoy(supermarioland_rom, window_type="dummy", game_wrapper=True)
    pyboy.set_emulation_speed(0)
    assert pyboy.cartridge_title() == "SUPER MARIOLAN"

    mario = pyboy.game_wrapper()
    mario.start_game(world_level=(1, 1))

    assert mario.score == 0
    assert mario.lives_left == 2
    assert mario.time_left == 400
    assert mario.world == (1, 1)
    assert mario.fitness == 0  # A built-in fitness score for AI development
    pyboy.stop()
예제 #3
0
def initialize_emulator(emu_conf={"gamerom": get_games_list()[0]}):

    gamerom = "roms/" + emu_conf["gamerom"]

    if "bootrom_file" in emu_conf:
        bootrom_file = emu_conf["bootrom_file"]
    else:
        bootrom_file = None

    if "profiling" in emu_conf:
        profiling = emu_conf["profiling"]
    else:
        profiling = False

    if "disable_renderer" in emu_conf:
        disable_renderer = emu_conf["disable_renderer"]
    else:
        disable_renderer = False

    if "sound" in emu_conf:
        sound = emu_conf["sound"]
    else:
        sound = True

    if "color_palette" in emu_conf:
        color_palette = rgb2bit(emu_conf["color_palette"])
    else:
        color_palette = rgb2bit("Blue")

    if "gamespeed" in emu_conf:
        gamespeed = emu_conf["gamespeed"]
    else:
        gamespeed = 0

    kwargs_pyboy = {
        "bootrom_file": bootrom_file,
        "profiling": profiling,
        "disable_renderer": disable_renderer,
        "sound": sound,
        "color_palette": color_palette
    }

    gameboy = PyBoy(gamerom, **kwargs_pyboy)
    gameboy.set_emulation_speed(gamespeed)
    print(gameboy.cartridge_title(), "speed:", gamespeed)
    if disable_renderer:
        gameboy.stop(save=False)

    return gameboy
예제 #4
0
def test_mario_advanced():
    pyboy = PyBoy(supermarioland_rom, window_type="dummy", game_wrapper=True)
    pyboy.set_emulation_speed(0)
    assert pyboy.cartridge_title() == "SUPER MARIOLAN"

    mario = pyboy.game_wrapper()
    mario.start_game(world_level=(3, 2))
    lives = 99
    mario.set_lives_left(lives)
    pyboy.tick()

    assert mario.score == 0
    assert mario.lives_left == lives
    assert mario.time_left == 400
    assert mario.world == (3, 2)
    assert mario.fitness == 10000 * lives + 6510  # A built-in fitness score for AI development
    pyboy.stop()
예제 #5
0
file_path = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, file_path + "/..")

from pyboy import PyBoy, WindowEvent # isort:skip

# Check if the ROM is given through argv
if len(sys.argv) > 1:
    filename = sys.argv[1]
else:
    print("Usage: python mario_boiler_plate.py [ROM file]")
    exit(1)

quiet = "--quiet" in sys.argv
pyboy = PyBoy(filename, window_type="headless" if quiet else "SDL2", window_scale=3, debug=not quiet, game_wrapper=True)
pyboy.set_emulation_speed(.1)
assert pyboy.cartridge_title() == "SUPER MARIOLAN"

mario = pyboy.game_wrapper()
mario.start_game()

assert mario.score == 0
assert mario.lives_left == 2
assert mario.time_left == 400
assert mario.world == (1, 1)
assert mario.fitness == 0 # A built-in fitness score for AI development
last_fitness = 0

print(mario)

pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)
for _ in range(1000):
예제 #6
0
file_path = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, file_path + "/..")

from pyboy import PyBoy, WindowEvent # isort:skip

# Check if the ROM is given through argv
if len(sys.argv) > 1:
    filename = sys.argv[1]
else:
    print("Usage: python mario_boiler_plate.py [ROM file]")
    exit(1)

quiet = "--quiet" in sys.argv
pyboy = PyBoy(filename, window_type="headless" if quiet else "SDL2", window_scale=3, debug=not quiet, game_wrapper=True)
pyboy.set_emulation_speed(0)
assert pyboy.cartridge_title() == "TETRIS"

tetris = pyboy.game_wrapper()
tetris.start_game(timer_div=0x00) # The timer_div works like a random seed in Tetris

assert tetris.next_tetromino() == "Z"
assert tetris.score == 0
assert tetris.level == 0
assert tetris.lines == 0
assert tetris.fitness == 0 # A built-in fitness score for AI development

blank_tile = 47
first_brick = False
for frame in range(1000): # Enough frames for the test. Otherwise do: `while not pyboy.tick():`
    pyboy.tick()
예제 #7
0
def replay(
    ROM,
    replay,
    window="headless",
    verify=True,
    record_gif=None,
    gif_destination=None,
    rewind=False,
    bootrom_file=utils.boot_rom,
    overwrite=RESET_REPLAYS,
    gif_hash=None,
    randomize=False
):
    with open(replay, "rb") as f:
        recorded_input, b64_romhash, b64_state = json.loads(zlib.decompress(f.read()).decode("ascii"))

    verify_file_hash(ROM, b64_romhash)
    state_data = io.BytesIO(base64.b64decode(b64_state.encode("utf8"))) if b64_state is not None else None

    pyboy = PyBoy(
        ROM,
        window_type=window,
        bootrom_file=bootrom_file,
        disable_input=True,
        rewind=rewind,
        randomize=randomize,
        record_input=(RESET_REPLAYS and window in ["SDL2", "headless", "OpenGL"])
    )
    pyboy.set_emulation_speed(0)
    if state_data is not None:
        pyboy.load_state(state_data)

    # Filters out the blacklisted events
    recorded_input = list(
        map(
            lambda event_tuple:
            (event_tuple[0], list(filter(lambda x: x not in event_filter, event_tuple[1])), event_tuple[2]),
            recorded_input
        )
    )

    frame_count = 0
    next_event = recorded_input.pop(0)

    recording = False
    while recorded_input != []:
        if record_gif is not None and (frame_count in record_gif):
            pyboy.send_input(WindowEvent.SCREEN_RECORDING_TOGGLE)
            recording ^= True

        if next_event[0] == frame_count:
            for e in next_event[1]:
                pyboy.send_input(e)

                if verify and not overwrite:
                    verify_screen_image_np(pyboy, base64.b64decode(next_event[2].encode("utf8")))
            next_event = recorded_input.pop(0)
        frame_count += 1
        # if frame_count % 30 == 0:
        #     print(frame_count)
        #     breakpoint()
        pyboy.tick()

    print(frame_count)
    # If end-frame in record_gif is high than frame counter
    if recording:
        pyboy.send_input(WindowEvent.SCREEN_RECORDING_TOGGLE)
        # We need to run an extra cycle for the screen recording to save
        pyboy.tick()
        print(frame_count)
        recording ^= True

    if gif_destination:
        move_gif(pyboy.cartridge_title(), gif_destination)
        if gif_hash is not None and not overwrite and sys.platform == "darwin":
            verify_file_hash(gif_destination, gif_hash)

    if overwrite:
        with open(replay, "wb") as f:
            f.write(
                zlib.compress(
                    json.dumps((pyboy.plugin_manager.record_replay.recorded_input, b64_romhash, b64_state)).encode()
                )
            )

    pyboy.stop(save=False)
예제 #8
0
class Environment:
    def __init__(self, filename, max_steps, visualize=False):

        self.pyboy = PyBoy(filename,
                           window_type="headless" if not visualize else "SDL2",
                           window_scale=3,
                           debug=visualize,
                           game_wrapper=True)
        assert self.pyboy.cartridge_title() == "SUPER MARIOLAN"

        self.pyboy.set_emulation_speed(0)
        self.mario = self.pyboy.game_wrapper()
        self.mario_lives = None
        self.mario_size = 0

        self.fitness_score = 0
        self.previous_fitness_score = 0
        self.previous_direction = 0
        self._level_progress_max = 0

        self.observation_space = (16, 20)
        self.action_space = [4]

        self.max_steps = max_steps

        self.pair_actions = {"5": 13, "3": 11, "4": 12, "0": 0}

        self.action_jump = [
            WindowEvent.PRESS_BUTTON_A, WindowEvent.RELEASE_BUTTON_A
        ]

        self.action_direction = [
            WindowEvent.PRESS_ARROW_LEFT, WindowEvent.PRESS_ARROW_RIGHT, 0
        ]

    def start(self):
        self.mario.start_game()
        self.mario_lives = self.mario.lives_left
        self.fitness_score = 0

    def reset(self):
        self.mario.reset_game()
        self.mario_lives = self.mario.lives_left
        self.mario_size = 0

        self.fitness_score = 0
        self.level_progress_max = 0
        # Compute first fitness score
        self.previous_fitness_score = self.compute_reward()
        self.previous_direction = 0

    def stop(self):
        self.pyboy.stop()

    def obs(self):
        game_area = self.normalize_input(self.mario.game_area())
        return game_area

    def normalize_input(self, game_area):

        game_area = np.asarray(game_area).astype('int64')

        if 32 in game_area and 49 in game_area:
            self.mario_size = torch.ones(1)
        else:
            self.mario_size = torch.zeros(1)

        mario = np.arange(70)
        mario = np.delete(mario, [15, 31])

        background = [
            336, 87, 89, 88, 91, 145, 168, 169, 128, 247, 248, 254, 300, 305,
            306, 307, 308, 310, 316, 328, 331, 332, 338, 339, 320, 321, 322,
            323, 324, 325, 326, 327, 329, 330, 338, 339, 350
        ]
        floor = [142, 143, 239, 352, 353, 232]
        block_bonus = 129
        bonus = [131, 132, 244, 246]
        ennemy = [
            144, 150, 151, 152, 153, 160, 161, 162, 163, 176, 177, 178, 179
        ]
        obstacle = [368, 130, 369, 355, 370, 371, 383]

        game_area[np.isin(game_area, mario)] = 1
        game_area[np.isin(game_area, mario)] = 1
        game_area[np.isin(game_area, background)] = 0
        game_area[np.isin(game_area, ennemy)] = 3
        game_area[np.isin(game_area, obstacle)] = 4
        game_area[np.isin(game_area, floor)] = 4
        game_area[game_area == block_bonus] = 5
        game_area[np.isin(game_area, bonus)] = 6
        return game_area

    def compute_reward(self):
        self.level_progress_max = max(self.mario.level_progress,
                                      self.level_progress_max)
        fitness = self.mario.score + self.mario.time_left * 10 + self.level_progress_max * 5 + self.mario.lives_left * 100
        return fitness

    def print_obs(self, game_area):

        print(
            "\n".join([
                f"{i: <3}| " + "".join([str(tile).ljust(4) for tile in line])
                for i, line in enumerate(game_area)
            ]), "\n")

    def step(self, actions=None):
        if actions is not None:
            direction = self.action_direction[actions[0]]
            jump = self.action_jump[actions[1]]

            if direction != self.previous_direction:
                # Release the previous direction
                end_action = self.pair_actions[str(self.previous_direction)]
                self.pyboy.send_input(end_action)
                self.previous_direction = direction

            self.pyboy.send_input(direction)
            self.pyboy.send_input(jump)
            for ministeps in range(6):
                self.pyboy.tick()

        else:
            for ministeps in range(5):
                self.pyboy.tick()

        # Compute reward
        self.fitness_score = self.compute_reward()

        reward = min(
            (self.fitness_score - self.previous_fitness_score), 100) / 100
        self.previous_fitness_score = self.fitness_score

        # Update fitness score
        self.fitness_score = self.mario.fitness

        new_state = torch.Tensor(self.obs())

        if (15 in new_state and 31 in new_state
            ) or self.mario.lives_left == 1:  # titles used for dead mario
            reward = -1
            done = True
        else:
            done = False

        return new_state, reward, done
예제 #9
0
# Check if the ROM is given through argv
if len(sys.argv) > 1:
    filename = sys.argv[1]
else:
    print("Usage: python gamewrapper_kirby.py [ROM file]")
    exit(1)

quiet = "--quiet" in sys.argv
pyboy = PyBoy(filename,
              window_type="headless" if quiet else "SDL2",
              window_scale=3,
              debug=not quiet,
              game_wrapper=True)
pyboy.set_emulation_speed(0)
assert pyboy.cartridge_title() == "KIRBY DREAM LA"

kirby = pyboy.game_wrapper()
kirby.start_game()

assert kirby.score == 0
assert kirby.lives_left == 4
assert kirby.health == 6

pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)

for _ in range(280):  # Walk for 280 ticks
    pyboy.tick()

assert kirby.score == 800
assert kirby.health == 5