Esempio n. 1
0
class RleTest(unittest.TestCase):
    def setUp(self):
        cwd = os.getcwd()
        core = 'snes'
        romName = os.path.join(cwd, 'roms', 'classic_kong.smc')
        self.rle = RLEInterface()
        self.rle.loadROM(romName, core)

    def test_ram(self):
        ram_size = self.rle.getRAMSize()
        self.assertEqual(128 * 1024, ram_size)
        ram = np.array(ram_size, dtype=np.uint8)
        ram = self.rle.getRAM()
        self.assertIsNotNone(ram[0])
        self.assertIsNotNone(ram[ram_size - 1])

    def test_getScreenRGB(self):
        dimensions = self.rle.getScreenDims()
        self.assertEqual(dimensions[0], 256)
        self.assertEqual(dimensions[1], 224)
        screen_data = np.empty((dimensions[1], dimensions[0], 4),
                               dtype=np.uint8)

        for _ in range(10):
            self.rle.act(0)
            self.rle.getScreenRGB(screen_data=screen_data)
            self.rle.getScreenGrayscale(screen_data=screen_data)

    def test_getScreenGrayscale(self):
        dimensions = self.rle.getScreenDims()
        self.assertEqual(dimensions[0], 256)
        self.assertEqual(dimensions[1], 224)
        screen_data = np.empty((dimensions[1], dimensions[0]), dtype=np.uint8)
        self.assertEqual(224 * 256, screen_data.size)
        for _ in range(100):
            self.rle.act(0)
        self.rle.getScreenGrayscale(screen_data=screen_data)
Esempio n. 2
0
# Set USE_SDL to true to display the screen. RLE must be compilied
# with SDL enabled for this to work. On OSX, pygame init is used to
# proxy-call SDL_main.
USE_SDL = False
if USE_SDL:
    if sys.platform == 'darwin':
        import pygame
        pygame.init()
        rle.setBool('sound', False)  # Sound doesn't work on OSX
    elif sys.platform.startswith('linux'):
        rle.setBool('sound', True)
    rle.setBool('display_screen', True)

# Load the ROM file
rle.loadROM(sys.argv[1], sys.argv[2])

# Get the list of legal actions
minimal_actions = rle.getMinimalActionSet()

# Play 10 episodes
for episode in range(10):
    total_reward = 0
    while not rle.game_over():
        a = minimal_actions[randrange(len(minimal_actions))]
        # Apply an action and get the resulting reward
        reward = rle.act(a)
        total_reward += reward
    print('Episode', episode, 'ended with score:', total_reward)
    rle.reset_game()
# Set USE_SDL to true to display the screen. ALE must be compilied
# with SDL enabled for this to work. On OSX, pygame init is used to
# proxy-call SDL_main.
USE_SDL = False
if USE_SDL:
  if sys.platform == 'darwin':
    import pygame
    pygame.init()
    rle.setBool('sound', False) # Sound doesn't work on OSX
  elif sys.platform.startswith('linux'):
    rle.setBool('sound', True)
  rle.setBool('display_screen', True)

# Load the ROM file
rle.loadROM(sys.argv[1], sys.argv[2])

# Get the list of legal actions
minimal_actions = rle.getMinimalActionSet()

# Play 10 episodes
for episode in xrange(10):
  total_reward = 0
  while not rle.game_over():
    a = minimal_actions[randrange(len(legal_actions))]
    # Apply an action and get the resulting reward
    reward = rle.act(a);
    total_reward += reward
  print 'Episode', episode, 'ended with score:', total_reward
  rle.reset_game()
Esempio n. 4
0
class RleEnv(gym.Env, utils.EzPickle):
    metadata = {'render.modes': ['human', 'rgb_array']}

    def __init__(self,
                 game='classic_kong',
                 obs_type='ram',
                 frameskip=(2, 5),
                 repeat_action_probability=0.):
        """Frameskip should be either a tuple (indicating a random range to
        choose from, with the top value exclude), or an int."""

        utils.EzPickle.__init__(self, game, obs_type)
        assert obs_type in ('ram', 'image')

        self.game_path = self.get_rom_path(game)

        self._obs_type = obs_type
        self.frameskip = frameskip
        self.rle = RLEInterface()
        self.viewer = None

        # Tune (or disable) RLE's action repeat:
        # https://github.com/openai/gym/issues/349
        assert isinstance(
            repeat_action_probability,
            (float, int)), "Invalid repeat_action_probability: {!r}".format(
                repeat_action_probability)
        self.rle.setFloat('repeat_action_probability'.encode('utf-8'),
                          repeat_action_probability)

        self._seed()

        (screen_width, screen_height) = self.rle.getScreenDims()
        self._buffer = np.empty((screen_height, screen_width, 4),
                                dtype=np.uint8)

        self._action_set = self.rle.getMinimalActionSet()
        self.action_space = spaces.Discrete(len(self._action_set))

        (screen_width, screen_height) = self.rle.getScreenDims()
        ram_size = self.rle.getRAMSize()
        if self._obs_type == 'ram':
            self.observation_space = spaces.Box(low=np.zeros(ram_size),
                                                high=np.zeros(ram_size) + 255)
        elif self._obs_type == 'image':
            self.observation_space = spaces.Box(low=0,
                                                high=255,
                                                shape=(
                                                    screen_height,
                                                    screen_width,
                                                ))
        else:
            raise error.Error('Unrecognized observation type: {}'.format(
                self._obs_type))

    def get_rom_path(self, game):
        cwd = os.path.dirname(__file__)
        roms_path = os.path.join(cwd, 'roms')
        for file in os.listdir(roms_path):
            if fnmatch.fnmatch(file, game + '*'):
                return os.path.join(roms_path, file)

    def _seed(self, seed=None):
        self.np_random, seed1 = seeding.np_random(seed)
        # Derive a random seed. This gets passed as a uint, but gets
        # checked as an int elsewhere, so we need to keep it below
        # 2**31.
        seed2 = seeding.hash_seed(seed1 + 1) % 2**31
        # Empirically, we need to seed before loading the ROM.
        self.rle.setInt(b'random_seed', seed2)
        self.rle.loadROM(self.game_path, 'snes')
        return [seed1, seed2]

    def _step(self, a):
        reward = 0.0
        action = self._action_set[a]

        if isinstance(self.frameskip, int):
            num_steps = self.frameskip
        else:
            num_steps = self.np_random.randint(self.frameskip[0],
                                               self.frameskip[1])
        for _ in range(num_steps):
            reward += self.rle.act(action)
        ob = self._get_obs()

        return ob, reward, self.rle.game_over(), {
            "rle.lives": self.rle.lives()
        }

    def _get_image(self):
        self.rle.getScreenRGB(self._buffer)
        return self._buffer[:, :, [0, 1, 2]]

    def _get_ram(self):
        return to_ram(self.rle)

    @property
    def _n_actions(self):
        return len(self._action_set)

    def _get_obs(self):
        if self._obs_type == 'ram':
            return self._get_ram()
        if self._obs_type == 'image':
            return self._get_image()

    def _reset(self):
        self.rle.reset_game()
        return self._get_obs()

    def _render(self, mode='human', close=False):
        if close:
            if self.viewer is not None:
                self.viewer.close()
                self.viewer = None
            return
        img = self._get_image()
        if mode == 'rgb_array':
            return img
        elif mode == 'human':
            from gym.envs.classic_control import rendering
            if self.viewer is None:
                self.viewer = rendering.SimpleImageViewer()
            self.viewer.imshow(img)

    def get_action_meanings(self):
        return [get_action_meaning(i) for i in self._action_set]