def __init__(self, value_mapping, colour_mapping):
        """Construct an `ObservationToArrayWithRGB`.

    Builds a callable that will take `Observation`s and emit a dictionary
    containing a 2-D and 3-D numpy array. The rows and columns of the 2-D array
    contain the values obtained after mapping the characters of the original
    `Observation` through `value_mapping`. The rows and columns of the 3-D array
    contain RGB values of the previous 2-D mapping in the [0,1] range.

    Args:
      value_mapping: a dict mapping any characters that might appear in the
          original `Observation`s to a scalar or 1-D vector value. All values
          in this dict must be the same type and dimension. Note that strings
          are considered 1-D vectors, not scalar values.
      colour_mapping: a dict mapping any characters that might appear in the
          original `Observation`s to a 3-tuple of RGB values in the range
          [0,999].

    """
        self._value_mapping = value_mapping
        self._colour_mapping = colour_mapping

        # Rendering functions for the `board` representation and `RGB` values.
        self._renderers = {
            'board':
            rendering.ObservationToArray(value_mapping=value_mapping,
                                         dtype=np.float32),
            # RGB should be np.uint8, but that will be applied in __call__,
            # since values here are outside of uint8 range.
            'RGB':
            rendering.ObservationToArray(value_mapping=colour_mapping)
        }
Example #2
0
    def __init__(self,
                 game,
                 num_apples=10,
                 apple_reward=1.,
                 fix_apple_reward_in_episode=False,
                 final_reward=10.,
                 crop=True,
                 default_reward=0):
        """Construct a `environment.Base` adapter that wraps a pycolab game."""
        rng = np.random.RandomState()
        if game == 'key_to_door':
            self._game = key_to_door.Game(rng, num_apples, apple_reward,
                                          fix_apple_reward_in_episode,
                                          final_reward, crop)
        elif game == 'active_visual_match':
            self._game = active_visual_match.Game(rng, num_apples,
                                                  apple_reward,
                                                  fix_apple_reward_in_episode,
                                                  final_reward)
        else:
            raise ValueError('Unsupported game "%s".' % game)
        self._default_reward = default_reward

        self._num_actions = self._game.num_actions
        # Agents expect HWC uint8 observations, Pycolab uses CHW float observations.
        #colours = nest.map_structure(lambda c: float(c) * 255 / 1000,
        #                             self._game.colours)
        colours = tf.nest.map_structure(lambda c: float(c) * 255 / 1000,
                                        self._game.colours)
        self._rgb_converter = rendering.ObservationToArray(
            value_mapping=colours, permute=(1, 2, 0), dtype=np.uint8)

        episode = self._game.make_episode()
        observation, _, _ = episode.its_showtime()
        self._image_shape = self._rgb_converter(observation).shape
def renderer(obs, scale=8):
    renderer_normal = rendering.ObservationToArray(COLOR_MAP, dtype=np.float32)
    obs_normal = renderer_normal(obs)
    obs_normal = trans_image(obs_normal)
    new_size = obs_normal.shape[1] * scale

    # Scale up the observation.
    scaled_img = np.stack([
        scipy.misc.imresize(obs_normal[:, :, i], [new_size, new_size, 1],
                            interp="nearest") for i in range(3)
    ],
                          axis=2)

    return np.transpose(scaled_img, (2, 1, 0))
    def testRendering(self):
        """Test various rendering utilities."""

        # This helper will allow us to compare numpy bool_ arrays with "art" drawn
        # as lists of '0' and '1' characters.
        def assertMask(actual_mask, mask_art, err_msg=''):  # pylint: disable=invalid-name
            np.testing.assert_array_equal(
                actual_mask,
                np.array([list(row) for row in mask_art]).astype(bool),
                err_msg)

        # Our test concerns renderings of this game world.
        art = ['..H..H..o..', '..HHHH..i..', '..H..H..i..']

        # Here we make the game. Note specification of Q, an empty Drape.
        engine = ascii_art.ascii_art_to_game(art=art,
                                             what_lies_beneath='.',
                                             drapes=dict(Q=tt.TestDrape))

        ### GAME ITERATION 0. We just run it to get an observation.

        observation, unused_reward, unused_discount = engine.its_showtime()

        ### Evaluate the observation's binary feature masks.

        # The observation's layer member should have an entry for all characters
        # that could be on the board, including ones for invisible Drapes.
        self.assertEqual(sorted(observation.layers.keys()),
                         sorted(list('.HioQ')))

        # Check that all the layer masks have the right contents.
        assertMask(observation.layers['.'],
                   ['11011011011', '11000011011', '11011011011'])

        assertMask(observation.layers['H'],
                   ['00100100000', '00111100000', '00100100000'])

        assertMask(observation.layers['i'],
                   ['00000000000', '00000000100', '00000000100'])

        assertMask(observation.layers['o'],
                   ['00000000100', '00000000000', '00000000000'])

        assertMask(observation.layers['Q'],
                   ['00000000000', '00000000000', '00000000000'])

        ### Test correct operation of ObservationCharacterRepainter.

        repainter = rendering.ObservationCharacterRepainter(
            dict(H='J', i='J', Q='M'))
        repainted = repainter(observation)

        # Check that the repainted board looks correct.
        self.assertBoard(repainted.board,
                         ['..J..J..o..', '..JJJJ..J..', '..J..J..J..'])

        # The repainted board should have these binary feature masks:
        self.assertEqual(sorted(repainted.layers.keys()), sorted(list('.JoM')))

        # The binary feature masks should have these contents:
        assertMask(repainted.layers['.'],
                   ['11011011011', '11000011011', '11011011011'])

        assertMask(repainted.layers['J'],
                   ['00100100000', '00111100100', '00100100100'])

        assertMask(repainted.layers['o'],
                   ['00000000100', '00000000000', '00000000000'])

        assertMask(repainted.layers['M'],
                   ['00000000000', '00000000000', '00000000000'])

        ### Test correct operation of ObservationToArray for 2-D and 3-D arrays.

        # For the 2-D conversion, we'll do our own "homebrew" repainter, but just
        # for the Observation.board representation. Recall that the board member of
        # an Observation is a 2-D array of uint8s.
        converter = rendering.ObservationToArray(
            {
                '.': ord(' '),
                'J': ord('#'),
                'o': ord('*'),
                'M': ord('?')
            },
            dtype=np.uint8)
        converted = converter(repainted)
        self.assertBoard(converted,
                         ['  #  #  *  ', '  ####  #  ', '  #  #  #  '])

        # Test that layer permutation happens correctly for the 2-D case.

        converter = rendering.ObservationToArray(
            {
                '.': ord(' '),
                'J': ord('#'),
                'o': ord('*'),
                'M': ord('?')
            },
            dtype=np.uint8,
            permute=(1, 0))
        converted = converter(repainted)
        self.assertBoard(converted, [
            '   ', '   ', '###', ' # ', ' # ', '###', '   ', '   ', '*##',
            '   ', '   '
        ])

        # For the 3-D conversion, we'll create a 3-D feature array that's a lot like
        # our feature masks.
        converter = rendering.ObservationToArray(
            {
                '.': (1, 0, 0, 0),
                'J': (0, 1, 0, 0),
                'o': (0, 0, 1, 0),
                'M': (0, 0, 0, 1)
            },
            dtype=bool)
        converted = converter(repainted)
        self.assertEqual(converted.shape, (4, 3, 11))

        assertMask(converted[0, :],
                   ['11011011011', '11000011011', '11011011011'])

        assertMask(converted[1, :],
                   ['00100100000', '00111100100', '00100100100'])

        assertMask(converted[2, :],
                   ['00000000100', '00000000000', '00000000000'])

        assertMask(converted[3, :],
                   ['00000000000', '00000000000', '00000000000'])

        # And another layer permutation test for the 3-D case.
        converter = rendering.ObservationToArray(
            {
                '.': (1, 0, 0, 0),
                'J': (0, 1, 0, 0),
                'o': (0, 0, 1, 0),
                'M': (0, 0, 0, 1)
            },
            dtype=bool,
            permute=(1, 2, 0))
        converted = converter(repainted)
        self.assertEqual(converted.shape, (3, 11, 4))

        assertMask(converted[..., 0],
                   ['11011011011', '11000011011', '11011011011'])

        assertMask(converted[..., 1],
                   ['00100100000', '00111100100', '00100100100'])

        assertMask(converted[..., 2],
                   ['00000000100', '00000000000', '00000000000'])

        assertMask(converted[..., 3],
                   ['00000000000', '00000000000', '00000000000'])

        ### Test ObservationToFeatureArray, which creates 3-D feature arrays faster.

        converter = rendering.ObservationToFeatureArray('.JoM')
        converted = converter(repainted)
        self.assertEqual(converted.shape, (4, 3, 11))

        assertMask(converted[0, :],
                   ['11011011011', '11000011011', '11011011011'])

        assertMask(converted[1, :],
                   ['00100100000', '00111100100', '00100100100'])

        assertMask(converted[2, :],
                   ['00000000100', '00000000000', '00000000000'])

        assertMask(converted[3, :],
                   ['00000000000', '00000000000', '00000000000'])

        ### Test ObservationToFeatureArray's layer permutation capability.

        converter = rendering.ObservationToFeatureArray('.J',
                                                        permute=(1, 0, 2))
        converted = converter(repainted)
        self.assertEqual(converted.shape, (3, 2, 11))

        assertMask(converted[0, :], ['11011011011', '00100100000'])

        assertMask(converted[1, :], ['11000011011', '00111100100'])

        assertMask(converted[2, :], ['11011011011', '00100100100'])
Example #5
0
def converter(obs):
    converter = rendering.ObservationToArray(COLOUR_FG, permute=(0, 1, 2))
    converted = np.swapaxes(converter(obs), 1, 2).T
    return converted