예제 #1
0
    def testCropping(self):
        """Observations from subgames can be cropped for mutual compatibility."""

        # The games will use these worlds.
        arts = [
            ['P..', '...', '...'],
            [
                '...............', '...............', '.......P.......',
                '...............', '...............'
            ],
            ['...', '...', 'P..'],
        ]

        # But these croppers will ensure that they all have a reasonable size.
        croppers = [
            None,
            cropping.FixedCropper(top_left_corner=(1, 6), rows=3, cols=3),
            cropping.FixedCropper(top_left_corner=(0, 0), rows=3, cols=3),
        ]

        # Create and start the story.
        story = storytelling.Story(
            chapters=[lambda art=a: self._make_game(art) for a in arts],
            croppers=croppers)
        observation, reward, pcontinue = story.its_showtime()
        del reward, pcontinue  # unused

        # For better narration of these observation comparisons, read through
        # testSequenceOfGames.
        self.assertBoard(observation.board, arts[0])
        self.assertMachinima(engine=story,
                             frames=[(None, ['...', '.P.', '...']),
                                     (None, arts[2]),
                                     (None, ['...', '...', '.P.'])])
def make_croppers(level):
    """Builds and returns `ObservationCropper`s for the selected level.

  We make three croppers for each level: one centred on the player, one centred
  on one of the Patrollers (scary!), and one centred on a tantalising hoard of
  coins somewhere in the level (motivating!)

  Args:
    level: level to make `ObservationCropper`s for.

  Returns:
    a list of three `ObservationCropper`s.
  """
    return [
        # The player view.
        cropping.ScrollingCropper(rows=10,
                                  cols=30,
                                  to_track=['P'],
                                  initial_offset=STARTER_OFFSET[level]),
        # The patroller view.
        cropping.ScrollingCropper(rows=7,
                                  cols=10,
                                  to_track=['c'],
                                  pad_char=' ',
                                  scroll_margins=(None, 3)),
        # The teaser!
        cropping.FixedCropper(top_left_corner=TEASER_CORNER[level],
                              rows=12,
                              cols=20,
                              pad_char=' '),
    ]
예제 #3
0
def make_croppers():
    """Builds and returns three `ObservationCropper`s for tennnn...nnnnis."""
    return [
        # Player 1 view.
        cropping.FixedCropper(top_left_corner=(0, 0), rows=10, cols=10),

        # The ball view.
        cropping.ScrollingCropper(rows=10,
                                  cols=31,
                                  to_track=['@'],
                                  scroll_margins=(0, None)),

        # Player 2 view.
        cropping.FixedCropper(top_left_corner=(0, len(MAZE_ART[0]) - 10),
                              rows=10,
                              cols=10),
    ]
예제 #4
0
    def testWeirdFixedCrops(self):
        """Cropping works even for strange cropping sizes and locations."""
        # All cropping in cropping.py uses the same cropping helper method, so
        # with this text and the prior one we try to cover a diverse range of
        # cropping situations.

        # Our test takes place in this world.
        art = [
            '.......', '.#####.', '.#P  #.', '.#   #.', '.#   #.', '.#####.',
            '.......'
        ]

        # Build several fixed croppers that crop in assorted odd ways.
        croppers = [
            # Extends beyond the original observation on all sides.
            cropping.FixedCropper((-1, -2), rows=9, cols=11, pad_char=' '),
            # A 1x1 crop right on the agent.
            cropping.FixedCropper((2, 2), rows=1, cols=1),
            # A long, short crop right through the agent.
            cropping.FixedCropper((2, -2), rows=1, cols=11, pad_char=' '),
            # A tall, skinny crop right through the agent.
            cropping.FixedCropper((-2, 2), rows=11, cols=1, pad_char=' '),
            # Altogether ouside of the observation.
            cropping.FixedCropper((-4, -4), rows=2, cols=2, pad_char=' '),
            # This, too
            cropping.FixedCropper((14, 14), rows=2, cols=2, pad_char=' '),
        ]

        # In a fresh engine, execute some actions and check for expected crops.
        self.assertMachinima(
            engine=self.make_engine(art, croppers),
            croppers=croppers,
            frames=[
                (
                    'stay',  # After executing this action...
                    [
                        [
                            '           ',
                            '  .......  ',  # ...we expect this from the first cropper...
                            '  .#####.  ',
                            '  .#P  #.  ',
                            '  .#   #.  ',
                            '  .#   #.  ',
                            '  .#####.  ',
                            '  .......  ',
                            '           '
                        ],
                        ['P'],  # ...and this from the second cropper...
                        ['  .#P  #.  '],  # ...and this from the third...
                        [c for c in '  .#P  #.  '
                         ],  # ...and this from the fourth...
                        [
                            '  ',  # ...fifth...
                            '  '
                        ],
                        [
                            '  ',  # ...and the sixth.
                            '  '
                        ]
                    ]),
            ],
        )
예제 #5
0
    def testFixedCropper(self):
        """Fixed croppers crop the designated part of the observation."""
        # All cropping in cropping.py uses the same cropping helper method, so
        # with this text and the next one we try to cover a diverse range of
        # cropping situations.

        # Our test takes place in this world.
        art = [
            '.......', '.#####.', '.#   #.', '.# P #.', '.#   #.', '.#####.',
            '.......'
        ]

        # Build several fixed croppers focusing on different parts of the board. All
        # have the same size, which lets us use zip to make our art easier to read.
        croppers = [
            # These croppers extend beyond all four corners of the game board,
            # allowing us to test the padding functionality.
            cropping.FixedCropper((-1, -1), rows=4, cols=4, pad_char=' '),
            cropping.FixedCropper((-1, 4), rows=4, cols=4, pad_char=' '),
            cropping.FixedCropper((4, -1), rows=4, cols=4, pad_char=' '),
            cropping.FixedCropper((4, 4), rows=4, cols=4, pad_char=' '),
            # This cropper sits right in the middle and requires no padding.
            cropping.FixedCropper((1, 1), rows=4, cols=4),
        ]

        # In a fresh engine, execute some actions and check for expected crops.
        # pylint: disable=bad-whitespace
        self.assertMachinima(
            engine=self.make_engine(art, croppers),
            croppers=croppers,
            frames=[
                (
                    'stay',  # The action, and cropped observations below.
                    zip(['    ', '    ', ' .# ', ' #. ', '####'],
                        [' ...', '... ', ' .##', '##. ', '#   '],
                        [' .##', '##. ', ' ...', '... ', '# P '],
                        [' .# ', ' #. ', '    ', '    ', '#   '])),
                ('nw',
                 zip(['    ', '    ', ' .# ', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#P  '],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .#P', ' #. ', '    ', '    ', '#   '])),
                ('e',
                 zip(['    ', '    ', ' .# ', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '# P '],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .# ', ' #. ', '    ', '    ', '#   '])),
                ('e',
                 zip(['    ', '    ', ' .# ', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#  P'],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .# ', 'P#. ', '    ', '    ', '#   '])),
                ('s',
                 zip(['    ', '    ', ' .# ', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#   '],
                     [' .##', '##. ', ' ...', '... ', '#  P'],
                     [' .# ', ' #. ', '    ', '    ', '#   '])),
                ('s',
                 zip(['    ', '    ', ' .# ', 'P#. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#   '],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .# ', ' #. ', '    ', '    ', '#  P'])),
                ('w',
                 zip(['    ', '    ', ' .# ', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#   '],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .# ', ' #. ', '    ', '    ', '# P '])),
                ('w',
                 zip(['    ', '    ', ' .#P', ' #. ', '####'],
                     [' ...', '... ', ' .##', '##. ', '#   '],
                     [' .##', '##. ', ' ...', '... ', '#   '],
                     [' .# ', ' #. ', '    ', '    ', '#P  '])),
            ],
        )