Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import base64
import hashlib
import io
import json
import os
import sys
import time
import zlib
import numpy as np
from pyboy import PyBoy, WindowEvent
from . import utils
event_filter = [
WindowEvent.PRESS_SPEED_UP,
WindowEvent.RELEASE_SPEED_UP,
WindowEvent.SCREEN_RECORDING_TOGGLE,
WindowEvent._INTERNAL_RENDERER_FLUSH,
]
# Set to true to reset tests
RESET_REPLAYS = False
def verify_screen_image_np(pyboy, saved_array):
match = np.all(
np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3) ==
pyboy.botsupport_manager().screen().screen_ndarray()
)
if not match:
from PIL import Image
original = Image.frombytes("RGB", (160, 144), np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3))
pyboy = PyBoy(tetris_rom, bootrom_file="pyboy_fast", window_type="headless", disable_input=True)
pyboy.set_emulation_speed(0)
first_brick = False
tile_map = pyboy.botsupport_manager().tilemap_window()
state_data = io.BytesIO()
for frame in range(5282): # Enough frames to get a "Game Over". Otherwise do: `while not pyboy.tick():`
pyboy.tick()
assert pyboy.botsupport_manager().screen().tilemap_position() == ((0, 0), (-7, 0))
# Start game. Just press Start and A when the game allows us.
# The frames are not 100% accurate.
if frame == 144:
pyboy.send_input(WindowEvent.PRESS_BUTTON_START)
elif frame == 145:
pyboy.send_input(WindowEvent.RELEASE_BUTTON_START)
elif frame == 152:
pyboy.send_input(WindowEvent.PRESS_BUTTON_A)
elif frame == 153:
pyboy.send_input(WindowEvent.RELEASE_BUTTON_A)
elif frame == 156:
pyboy.send_input(WindowEvent.PRESS_BUTTON_A)
elif frame == 157:
pyboy.send_input(WindowEvent.RELEASE_BUTTON_A)
elif frame == 162:
pyboy.send_input(WindowEvent.PRESS_BUTTON_A)
elif frame == 163:
pyboy.send_input(WindowEvent.RELEASE_BUTTON_A)
# Play game. When we are passed the 168th frame, the game has begone.
def test_record_replay():
pyboy = PyBoy(tetris_rom, window_type="headless", bootrom_file=boot_rom, record_input=True)
pyboy.set_emulation_speed(0)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_UP)
pyboy.tick()
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_UP)
pyboy.tick()
events = pyboy.plugin_manager.record_replay.recorded_input
assert len(events) == 4, "We assumed only 4 frames were recorded, as frames without events are skipped."
frame_no, keys, frame_data = events[0]
assert frame_no == 1, "We inserted the key on the second frame"
assert keys[0] == WindowEvent.PRESS_ARROW_DOWN, "Check we have the right keypress"
assert sum(base64.b64decode(frame_data)) / 0xFF == 144 * 160 * 3, "Frame does not contain 160x144 of RGB data"
pyboy.stop(save=False)
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_DOWN)
for n in range(3):
pyboy.send_input(WindowEvent.PRESS_ARROW_LEFT)
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_LEFT)
pyboy.tick()
tetris.set_tetromino("O")
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
while tetris.score == 16:
pyboy.tick()
pyboy.tick()
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_DOWN)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
while tetris.score == 32:
pyboy.tick()
pyboy.tick()
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_DOWN)
while tetris.score == 47:
pyboy.tick()
pyboy.tick()
pyboy.tick()
assert tetris.score == 87
assert tetris.lines == 1
import json
import os
import sys
import time
import zlib
import numpy as np
from pyboy import PyBoy, WindowEvent
from . import utils
event_filter = [
WindowEvent.PRESS_SPEED_UP,
WindowEvent.RELEASE_SPEED_UP,
WindowEvent.SCREEN_RECORDING_TOGGLE,
WindowEvent._INTERNAL_RENDERER_FLUSH,
]
# Set to true to reset tests
RESET_REPLAYS = False
def verify_screen_image_np(pyboy, saved_array):
match = np.all(
np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3) ==
pyboy.botsupport_manager().screen().screen_ndarray()
)
if not match:
from PIL import Image
original = Image.frombytes("RGB", (160, 144), np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3))
original.show()
new = pyboy.botsupport_manager().screen().screen_image()
new.show()
def test_tilemap_position_list():
pyboy = PyBoy(supermarioland_rom, window_type="headless", disable_input=True)
for _ in range(100):
pyboy.tick()
# Start the game
pyboy.send_input(WindowEvent.PRESS_BUTTON_START)
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_BUTTON_START)
# Move right for 100 frame
pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)
for _ in range(100):
pyboy.tick()
# Get screen positions, and verify the values
positions = pyboy.botsupport_manager().screen().tilemap_position_list()
for y in range(1, 16):
assert positions[y][0] == 0 # HUD
for y in range(16, 144):
assert positions[y][0] == 49 # Actual screen position
# Progress another 10 frames to see and increase in SCX
for _ in range(10):
pyboy.tick()
# Get screen positions, and verify the values
positions = pyboy.botsupport_manager().screen().tilemap_position_list()
def test_tetris(self, pyboy):
tetris = pyboy.game_wrapper()
tetris.set_tetromino("I")
tetris.start_game()
assert tetris.score == 0
assert tetris.lines == 0
for n in range(3):
pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_RIGHT)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
while tetris.score == 0:
pyboy.tick()
pyboy.tick()
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_DOWN)
for n in range(3):
pyboy.send_input(WindowEvent.PRESS_ARROW_LEFT)
pyboy.tick()
pyboy.send_input(WindowEvent.RELEASE_ARROW_LEFT)
pyboy.tick()
def test_mario_game_over():
pyboy = PyBoy(supermarioland_rom, window_type="dummy", game_wrapper=True)
pyboy.set_emulation_speed(0)
mario = pyboy.game_wrapper()
mario.start_game()
mario.set_lives_left(0)
pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)
for _ in range(500): # Enough to game over correctly, and not long enough it'll work without setting the lives
pyboy.tick()
if mario.game_over():
break
pyboy.stop()
def test_record_replay():
pyboy = PyBoy(tetris_rom, window_type="headless", bootrom_file=boot_rom, record_input=True)
pyboy.set_emulation_speed(0)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_UP)
pyboy.tick()
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
pyboy.tick()
pyboy.send_input(WindowEvent.PRESS_ARROW_UP)
pyboy.tick()
events = pyboy.plugin_manager.record_replay.recorded_input
assert len(events) == 4, "We assumed only 4 frames were recorded, as frames without events are skipped."
frame_no, keys, frame_data = events[0]
assert frame_no == 1, "We inserted the key on the second frame"
assert keys[0] == WindowEvent.PRESS_ARROW_DOWN, "Check we have the right keypress"
assert sum(base64.b64decode(frame_data)) / 0xFF == 144 * 160 * 3, "Frame does not contain 160x144 of RGB data"
assert tetris.next_tetromino() == "O"
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()
# The playing "technique" is just to move the Tetromino to the right.
if frame % 2 == 0: # Even frames
pyboy.send_input(WindowEvent.PRESS_ARROW_RIGHT)
elif frame % 2 == 1: # Odd frames
pyboy.send_input(WindowEvent.RELEASE_ARROW_RIGHT)
# Illustrating how we can extract the game board quite simply. This can be used to read the tile identifiers.
game_area = tetris.game_area()
# game_area is accessed as [, ].
# 'game_area[-1,:]' is asking for all (:) the columns in the last row (-1)
if not first_brick and any(filter(lambda x: x != blank_tile, game_area[-1, :])):
first_brick = True
print("First brick touched the bottom!")
print(tetris)
print("Final game board mask:")
print(tetris)
# We shouldn't have made any progress with the moves we made
assert tetris.score == 0
assert tetris.level == 0