示例#1
0
 def simple_flood(self):
     map_size = 21
     flooded_tiles = [[1] * map_size for _ in range(map_size)]
     flooded_tiles[5][5] = 0
     flooded_tiles[5][6] = 0
     flooded_tiles[6][5] = 0
     flooded_tiles[6][6] = 0
     flood(flooded_tiles, 1, 0)
示例#2
0
 def test_open_path(self):
     tiles = [
         # fmt: off
         [1, 1, 1, 1, 1],
         [1, 0, 1, 1, 1],
         [1, 0, 1, 1, 1],
         [1, 0, 0, 0, 1],
         [1, 1, 1, 1, 1]
         # fmt: on
     ]
     size = len(tiles)
     flood(tiles, 1, 0)
     self.assertEqual(tiles, [[0] * size for _ in range(size)])
示例#3
0
    def test_closed_box(self):
        tiles = [
            # fmt: off
            [1, 1, 1, 1, 1],
            [1, 0, 0, 0, 1],
            [1, 0, 1, 0, 1],
            [1, 0, 0, 0, 1],
            [1, 1, 1, 1, 1]
            # fmt: on
        ]
        flood(tiles, 1, 0)

        expected = [
            # fmt: off
            [0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0]
            # fmt: on
        ]
        self.assertEqual(tiles, expected)
示例#4
0
    def test_closed_box_corner(self):
        # This test case is not possible by construction wince we have an asteroids around the map
        tiles = [
            # fmt: off
            [1, 0, 1, 1, 1],
            [1, 0, 1, 1, 1],
            [1, 0, 1, 1, 1],
            [1, 0, 0, 0, 0],
            [1, 1, 1, 1, 1]
            # fmt: on
        ]
        flood(tiles, 1, 0)

        expected = [
            # fmt: off
            [0, 0, 1, 1, 1],
            [0, 0, 1, 1, 1],
            [0, 0, 1, 1, 1],
            [0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0]
            # fmt: on
        ]
        self.assertEqual(tiles, expected)
示例#5
0
    def fill(self, player: PlayerState) -> Set[Position]:
        id = player.id

        # tail have the starting and ending tiles (last tile before going in the empty zone and first captured tile)
        assert len(player.tail) >= 3
        assert self.game_map.is_conquered_by(player.tail[0], id)
        assert self.game_map.is_conquered_by(player.tail[-1], id)

        # new captured tiles minus start and end tiles (already captured)
        new_conquers = set(player.tail[1:-1])

        # check if we have a closed loop to fill: find shortest path from start to end of tail while walking only on conquered tiles
        closed_loop, shortest_path_to_close_tail = self.game_map.find_path(
            player.tail[0], player.tail[-1], id)
        if closed_loop:
            # Conquer the closed shape made by the tail
            map_size = self.game_map.size
            flooded_tiles = [[1] * map_size for _ in range(map_size)]

            for p in player.tail:
                flooded_tiles[p.y][p.x] = 0
            for p in shortest_path_to_close_tail:
                flooded_tiles[p.y][p.x] = 0

            # flooding work by changing the value to 0 for every reachable tiles from the top left of the map (skipping bombs,
            # walls and other players)  The remainder are the tiles that will be flooded. Using the closest path from start
            # to end of the tail make sure that we are filling only the smallest zone  when wrap around and also make sure we
            # do not re-kill any players walking inside our captured zone.
            flood(flooded_tiles, target=1, replacement=0)

            for y in range(map_size):
                for x in range(map_size):
                    if flooded_tiles[y][x] == 1:
                        p = Position(x, y)

                        # skip already conquered tiles or walls (asteroids)
                        if not self.game_map.is_conquered_by(
                                p, id) and not self.game_map.is_asteroids(p):
                            if self.game_map.is_black_hole(p):
                                # if we happen to surround a black hole, we die instantly
                                self.stepped_on_a_black_hole(p, player)
                                return set()

            for y in range(map_size):
                for x in range(map_size):
                    if flooded_tiles[y][x] == 1:
                        p = Position(x, y)

                        # skip already conquered tiles or walls (asteroids)
                        if not self.game_map.is_conquered_by(
                                p, id) and not self.game_map.is_asteroids(p):
                            if self.game_map.is_blitzium(p):
                                # surrounding a coin (blitzium) will give us more points.
                                self.check_if_captured_a_blitzium(p, player)

                            # add tile to new conquered tiles for later scoring
                            new_conquers.add(p)
                            self.game_map.conquer_tile(p, id)

        # capture the tail (no-op to recapture start and end tiles)
        for t in player.tail:
            self.game_map.conquer_tile(t, id)
        player.tail = [player.position.copy()]

        # adjust stats
        nb_conquers = len(new_conquers)
        self.logger.info(
            f"Player '{player.name_str()}' is capturing {nb_conquers} new tiles.."
        )
        player.stats.set_stat(
            PlayerStats.CONQUERED,
            player.stats.stats[PlayerStats.CONQUERED] + nb_conquers)
        player.score += GameState.SCORE_NEW_CONQUERED * nb_conquers
        player.add_history(self.game_tick,
                           f"Conquered {nb_conquers} new tiles.")
        return new_conquers
示例#6
0
 def test_all(self):
     size = 10
     tiles = [[1] * size for _ in range(size)]
     flood(tiles, 1, 0)
     self.assertEqual(tiles, [[0] * size for _ in range(size)])