def idle(self): '''Called during each iteration of the event loop. The method is called immediately after any window events (i.e., after any user input). The method can return a duration after which the idle method will be called again. The method may be called earlier if the user creates more input events. The method can return `None` to only wait for user events. For example, return ``1.0`` to have the idle method called every second, or immediately after any user events. The default implementation dispatches the `pyglet.window.Window.on_draw` event for all windows and uses `pyglet.clock.tick` and `pyglet.clock.get_sleep_time` on the default clock to determine the return value. This method should be overridden by advanced users only. To have code execute at regular intervals, use the `pyglet.clock.schedule` methods. :rtype: float :return: The number of seconds before the idle method should be called again, or `None` to block for user input. ''' dt = clock.tick(True) # Redraw all windows for window in windows: window.switch_to() window.dispatch_event('on_draw') window.flip() # Update timout return clock.get_sleep_time(True)
def idle(self): '''Called during each iteration of the event loop. The method is called immediately after any window events (i.e., after any user input). The method can return a duration after which the idle method will be called again. The method may be called earlier if the user creates more input events. The method can return `None` to only wait for user events. For example, return ``1.0`` to have the idle method called every second, or immediately after any user events. The default implementation dispatches the `pyglet.window.Window.on_draw` event for all windows and uses `pyglet.clock.tick` and `pyglet.clock.get_sleep_time` on the default clock to determine the return value. This method should be overridden by advanced users only. To have code execute at regular intervals, use the `pyglet.clock.schedule` methods. :rtype: float :return: The number of seconds before the idle method should be called again, or `None` to block for user input. ''' dt = clock.tick(True) # Redraw all windows for window in windows: if window.invalid: window.switch_to() window.dispatch_event('on_draw') window.flip() # Update timout return clock.get_sleep_time(True)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--game', help='retro game to use') parser.add_argument('--state', help='retro state to start from') parser.add_argument('--scenario', help='scenario to use', default='scenario') args = parser.parse_args() if args.game is None: print('Please specify a game with --game <game>') print('Available games:') for game in sorted(retro.data.list_games()): print(game) sys.exit(1) if args.state is None: print('Please specify a state with --state <state>') print('Available states:') for state in sorted(retro.data.list_states(args.game)): print(state) sys.exit(1) env = retro.make(game=args.game, state=args.state, use_restricted_actions=retro.Actions.ALL, scenario=args.scenario) obs = env.reset() screen_height, screen_width = obs.shape[:2] random.seed(0) key_handler = pyglet.window.key.KeyStateHandler() win_width = 2000 win_height = win_width * screen_height // screen_width win = pyglet.window.Window(width=win_width, height=win_height, vsync=False) if hasattr(win.context, '_nscontext'): pixel_scale = win.context._nscontext.view().backingScaleFactor() win.width = win.width // pixel_scale win.height = win.height // pixel_scale joysticks = pyglet.input.get_joysticks() if len(joysticks) > 0: joystick = joysticks[0] joystick.open() else: joystick = None win.push_handlers(key_handler) key_previous_states = {} button_previous_states = {} steps = 0 recorded_actions = [] recorded_states = [] pyglet.app.platform_event_loop.start() fps_display = pyglet.clock.ClockDisplay() clock.set_fps_limit(60) glEnable(GL_TEXTURE_2D) texture_id = GLuint(0) glGenTextures(1, ctypes.byref(texture_id)) glBindTexture(GL_TEXTURE_2D, texture_id) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, None) while not win.has_exit: win.dispatch_events() win.clear() keys_clicked = set() keys_pressed = set() for key_code, pressed in key_handler.items(): if pressed: keys_pressed.add(key_code) if not key_previous_states.get(key_code, False) and pressed: keys_clicked.add(key_code) key_previous_states[key_code] = pressed buttons_clicked = set() buttons_pressed = set() if joystick is not None: for button_code, pressed in enumerate(joystick.buttons): if pressed: buttons_pressed.add(button_code) if not button_previous_states.get(button_code, False) and pressed: buttons_clicked.add(button_code) button_previous_states[button_code] = pressed if keycodes.R in keys_clicked or buttoncodes.LEFT_BUMPER in buttons_clicked: if len(recorded_states) > 1: recorded_states.pop() steps, save_state = recorded_states.pop() recorded_states = recorded_states[:steps] recorded_actions = recorded_actions[:steps] env.em.set_state(save_state) if keycodes.ESCAPE in keys_pressed or buttoncodes.XBOX in buttons_clicked: # record all the actions so far to a bk2 and exit i = 0 while True: movie_filename = 'human/%s/%s/%s-%s-%04d.bk2' % (args.game, args.scenario, args.game, args.state, i) if not os.path.exists(movie_filename): break i += 1 os.makedirs(os.path.dirname(movie_filename), exist_ok=True) env.record_movie(movie_filename) env.reset() for step, act in enumerate(recorded_actions): if step % 1000 == 0: print('saving %d/%d' % (step, len(recorded_actions))) env.step(act) env.stop_record() print('complete') sys.exit(1) inputs = { 'A': keycodes.Z in keys_pressed or buttoncodes.A in buttons_pressed, 'B': keycodes.X in keys_pressed or buttoncodes.B in buttons_pressed, 'C': keycodes.C in keys_pressed, 'X': keycodes.A in keys_pressed or buttoncodes.X in buttons_pressed, 'Y': keycodes.S in keys_pressed or buttoncodes.Y in buttons_pressed, 'Z': keycodes.D in keys_pressed, 'UP': keycodes.UP in keys_pressed or buttoncodes.D_UP in buttons_pressed, 'DOWN': keycodes.DOWN in keys_pressed or buttoncodes.D_DOWN in buttons_pressed, 'LEFT': keycodes.LEFT in keys_pressed or buttoncodes.D_LEFT in buttons_pressed, 'RIGHT': keycodes.RIGHT in keys_pressed or buttoncodes.D_RIGHT in buttons_pressed, 'MODE': keycodes.TAB in keys_pressed or buttoncodes.SELECT in buttons_pressed, 'START': keycodes.ENTER in keys_pressed or buttoncodes.START in buttons_pressed, } action = [inputs[b] for b in env.buttons] if steps % SAVE_PERIOD == 0: recorded_states.append((steps, env.em.get_state())) obs, rew, done, info = env.step(action) recorded_actions.append(action) steps += 1 glBindTexture(GL_TEXTURE_2D, texture_id) video_buffer = ctypes.cast(obs.tobytes(), ctypes.POINTER(ctypes.c_short)) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, obs.shape[1], obs.shape[0], GL_RGB, GL_UNSIGNED_BYTE, video_buffer) x = 0 y = 0 h = win.height w = win.width pyglet.graphics.draw( 4, pyglet.gl.GL_QUADS, ('v2f', [x, y, x + w, y, x + w, y + h, x, y + h]), ('t2f', [0, 1, 1, 1, 1, 0, 0, 0]), ) fps_display.draw() win.flip() # process joystick events timeout = clock.get_sleep_time(False) pyglet.app.platform_event_loop.step(timeout) clock.tick() pyglet.app.platform_event_loop.stop()
def play(game='SonicTheHedgehog-Genesis', state='GreenHillZone.Act1', scenario='scenario', frame_jump=1): ''' :param game: game to load :param state: level to load :param scenario: scenario to load :return: ''' print('\n\tBACKSPACE : reset the level' '\n\tECHAP : End') jump = 0 env = retro.make(game=game, state=state, use_restricted_actions=retro.ACTIONS_ALL, scenario=scenario) obs = env.reset() win_width = 900 screen_height, screen_width = obs.shape[:2] win_height = win_width * screen_height // screen_width win = pyglet.window.Window(width=win_width, height=win_height, vsync=False) key_handler = pyglet.window.key.KeyStateHandler() win.push_handlers(key_handler) key_previous_states = {} pyglet.app.platform_event_loop.start() fps_display = pyglet.clock.ClockDisplay() clock.set_fps_limit(60) glEnable(GL_TEXTURE_2D) texture_id = GLuint(0) glGenTextures(1, ctypes.byref(texture_id)) glBindTexture(GL_TEXTURE_2D, texture_id) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, None) total_reward = 0.0 while not win.has_exit: win.dispatch_events() win.clear() keys_clicked = set() keys_pressed = set() for key_code, pressed in key_handler.items(): if pressed: keys_pressed.add(key_code) if not key_previous_states.get(key_code, False) and pressed: keys_clicked.add(key_code) key_previous_states[key_code] = pressed buttons_pressed = set() # End of the session if keycodes.ESCAPE in keys_pressed: pyglet.app.platform_event_loop.stop() return # Reset of the level and the recorded images and actions elif keycodes.BACKSPACE in keys_pressed: print('reset level') env.reset() inputs = { 'A': keycodes.Z in keys_pressed or ButtonCodes.A in buttons_pressed, 'B': keycodes.A in keys_pressed or ButtonCodes.B in buttons_pressed, 'C': keycodes.E in keys_pressed, 'X': keycodes.Q in keys_pressed or ButtonCodes.X in buttons_pressed, 'Y': keycodes.S in keys_pressed or ButtonCodes.Y in buttons_pressed, 'Z': keycodes.D in keys_pressed, 'UP': keycodes.UP in keys_pressed or ButtonCodes.D_UP in buttons_pressed, 'DOWN': keycodes.DOWN in keys_pressed or ButtonCodes.D_DOWN in buttons_pressed, 'LEFT': keycodes.LEFT in keys_pressed or ButtonCodes.D_LEFT in buttons_pressed, 'RIGHT': keycodes.RIGHT in keys_pressed or ButtonCodes.D_RIGHT in buttons_pressed, 'MODE': keycodes.TAB in keys_pressed or ButtonCodes.SELECT in buttons_pressed, 'START': keycodes.ENTER in keys_pressed or ButtonCodes.START in buttons_pressed, } if jump == 0: action = [inputs[b] for b in env.BUTTONS] last_action = action obs, rew, done, info = env.step(action) jump = frame_jump else: obs, rew, done, info = env.step(last_action) total_reward += rew print(total_reward) print(rew) jump -= 1 glBindTexture(GL_TEXTURE_2D, texture_id) video_buffer = ctypes.cast(obs.tobytes(), ctypes.POINTER(ctypes.c_short)) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, obs.shape[1], obs.shape[0], GL_RGB, GL_UNSIGNED_BYTE, video_buffer) x = 0 y = 0 h = win.height w = win.width pyglet.graphics.draw(4, pyglet.gl.GL_QUADS, ('v2f', [x, y, x + w, y, x + w, y + h, x, y + h]), ('t2f', [0, 1, 1, 1, 1, 0, 0, 0]), ) fps_display.draw() win.flip() timeout = clock.get_sleep_time(False) pyglet.app.platform_event_loop.step(timeout) clock.tick() pyglet.app.platform_event_loop.stop()
def generate_data(game='SonicTheHedgehog-Genesis', state='GreenHillZone.Act1', scenario='scenario', extension_name='', frame_jump=1, save_images=True, save_actions=True, fixed_record_size=False): ''' Play to Sonic and save the images and actions of the session in order to create data for neural networks trainings :param game: game to load :param state: level to load :param scenario: the scenario file :param extension_name: extension's name of the image arrays and actions that will be saved :param frame_jump: factor for not saving images ex :frame_jump = 1 : every image of the session is saved frame_jump = 3 : only 1/3 images are saved The last action is repeated during the jumped frames :return: Actions : Move Sonic : Directional arrows Z : Jump S : Down R : Save session (images + actions). The name of the save will end by extension_name + an index which is incremented every save. C : Cancel current recording (images + actions are cleaned) BackSpace : level reset (images + actions are cleaned) ''' print('\n\tBACKSPACE : reset level' '\n\tC : Cancel current recording' '\n\tR : Save current recording' '\n\tECHAP : End') jump = 0 # Level loading env = retro.make(game=game, state=state, use_restricted_actions=retro.ACTIONS_ALL, scenario=scenario) obs = env.reset() save_index = 1 win_width = 900 screen_height, screen_width = obs.shape[:2] win_height = win_width * screen_height // screen_width win = pyglet.window.Window(width=win_width, height=win_height, vsync=False) key_handler = pyglet.window.key.KeyStateHandler() win.push_handlers(key_handler) key_previous_states = {} pyglet.app.platform_event_loop.start() fps_display = pyglet.clock.ClockDisplay() clock.set_fps_limit(60) glEnable(GL_TEXTURE_2D) texture_id = GLuint(0) glGenTextures(1, ctypes.byref(texture_id)) glBindTexture(GL_TEXTURE_2D, texture_id) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, None) # Array of the session's images images = [] # Array of the session's actions actions = [] while not win.has_exit: win.dispatch_events() win.clear() keys_clicked = set() keys_pressed = set() for key_code, pressed in key_handler.items(): if pressed: keys_pressed.add(key_code) if not key_previous_states.get(key_code, False) and pressed: keys_clicked.add(key_code) key_previous_states[key_code] = pressed buttons_pressed = set() # End of the session if keycodes.ESCAPE in keys_pressed: pyglet.app.platform_event_loop.stop() return # Reset images and actions elif keycodes.C in keys_pressed: print('reset record') print(len(images)) images = [] actions = [] # Images and actions of the game session are saved elif fixed_record_size and len(images) == SEQ_LENGTH + 1: if save_images: images = np.array(images, dtype=np.uint8) np.save('./data/images/' + state + extension_name + str(save_index), images) print('Images saved at : ./data/images/' + state + extension_name + str(save_index)) if save_actions: actions = np.array(actions, dtype=np.bool) np.save('./data/actions/' + state + extension_name + str(save_index), actions) print('Actions saved at : ./data/actions/' + state + extension_name + str(save_index)) images = [] actions = [] save_index += 1 elif keycodes.R in keys_pressed: if save_images and len(images) > 10: images = np.array(images, dtype=np.uint8) np.save('./data/images/' + state + extension_name + str(save_index), images) print('Images saved at : ./data/images/' + state + extension_name + str(save_index)) if save_actions and len(actions) > 10: actions = np.array(actions, dtype=np.bool) np.save('./data/actions/' + state + extension_name + str(save_index), actions) print('Actions saved at : ./data/actions/' + state + extension_name + str(save_index)) images = [] actions = [] save_index += 1 # Reset of the level, actions and images elif keycodes.BACKSPACE in keys_pressed: print('level reset') env.reset() images = [] actions = [] inputs = { 'A': keycodes.Z in keys_pressed or ButtonCodes.A in buttons_pressed, 'B': keycodes.A in keys_pressed or ButtonCodes.B in buttons_pressed, 'C': keycodes.E in keys_pressed, 'X': keycodes.Q in keys_pressed or ButtonCodes.X in buttons_pressed, 'Y': keycodes.S in keys_pressed or ButtonCodes.Y in buttons_pressed, 'Z': keycodes.D in keys_pressed, 'UP': keycodes.UP in keys_pressed or ButtonCodes.D_UP in buttons_pressed, 'DOWN': keycodes.DOWN in keys_pressed or ButtonCodes.D_DOWN in buttons_pressed, 'LEFT': keycodes.LEFT in keys_pressed or ButtonCodes.D_LEFT in buttons_pressed, 'RIGHT': keycodes.RIGHT in keys_pressed or ButtonCodes.D_RIGHT in buttons_pressed, 'MODE': keycodes.TAB in keys_pressed or ButtonCodes.SELECT in buttons_pressed, 'START': keycodes.ENTER in keys_pressed or ButtonCodes.START in buttons_pressed, } if jump == 0: action = [inputs[b] for b in env.BUTTONS] last_action = action obs, rew, done, info = env.step(action) jump = frame_jump if save_images: images.append(obs) if save_actions: actions.append([inputs['A'], inputs['LEFT'], inputs['RIGHT'], inputs['DOWN']]) else: obs, rew, done, info = env.step(last_action) jump -= 1 glBindTexture(GL_TEXTURE_2D, texture_id) video_buffer = ctypes.cast(obs.tobytes(), ctypes.POINTER(ctypes.c_short)) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, obs.shape[1], obs.shape[0], GL_RGB, GL_UNSIGNED_BYTE, video_buffer) x = 0 y = 0 h = win.height w = win.width pyglet.graphics.draw(4, pyglet.gl.GL_QUADS, ('v2f', [x, y, x + w, y, x + w, y + h, x, y + h]), ('t2f', [0, 1, 1, 1, 1, 0, 0, 0]), ) fps_display.draw() win.flip() timeout = clock.get_sleep_time(False) pyglet.app.platform_event_loop.step(timeout) clock.tick() pyglet.app.platform_event_loop.stop()
def idle(loop): clock.tick(poll=True) return clock.get_sleep_time(sleep_idle=True) / 2.0