Пример #1
0
    def test_find_path_empty_tiles(self):
        map = create_map_with([
            # fmt: off
            [1, E, E, E],
            [W, W, E, E],
            [W, E, E, W],
            [2, E, W, E]
            # fmt: on
        ])
        found, path = map.find_path(start=Position(1, 1), goal=Position(4, 1))
        self.assertTrue(found)
        self.assertEqual(len(path), 4)
        self.assertEqual(
            path,
            [Position(1, 1),
             Position(2, 1),
             Position(3, 1),
             Position(4, 1)])

        found, path = map.find_path(start=Position(1, 1), goal=Position(1, 4))
        self.assertTrue(found)
        self.assertEqual(len(path), 8)

        found, path = map.find_path(start=Position(1, 1), goal=Position(4, 4))
        self.assertFalse(found)
Пример #2
0
    def test_get_set_tile(self):
        """
        Test that you can set a tile and get it back
        """
        position = Position(x=2, y=1)
        old_is_empty = self.my_map.empty_tiles
        self.assertTrue(self.my_map.is_empty(position))
        self.assertEqual(self.my_map.get_tile(position), GameMap.empty_tile)

        # conquer empty tile is the same as setting an owner on it
        self.my_map.set_tile(position, GameMap.EMPTY, 1)
        self.assertFalse(self.my_map.is_empty(position))
        self.assertTrue(self.my_map.is_conquered_by(position, 1))
        self.assertEqual(self.my_map.get_owner(position), 1)
        self.assertEqual(self.my_map.get_tile(position), (GameMap.EMPTY, 1))
        self.assertEqual(self.my_map.empty_tiles, old_is_empty - 1)

        # clear tile remove owner
        self.my_map.clear_tile(position)
        self.assertTrue(self.my_map.is_empty(position))
        self.assertEqual(self.my_map.get_tile(position)[0], GameMap.EMPTY)
        self.assertEqual(self.my_map.empty_tiles, old_is_empty)

        with self.assertRaises(OutOfBoundExeption):
            self.my_map.get_tile(
                Position(self.map_size + 10, self.map_size + 10))

        with self.assertRaises(OutOfBoundExeption):
            self.my_map.set_tile(
                Position(self.map_size + 10, self.map_size + 10),
                GameMap.EMPTY, 1)
Пример #3
0
    def test_init_with_empty_map(self):
        """
        Test that a new map will be empty and the correct size
        """
        self.assertEqual(self.my_map.size, self.map_size)
        self.assertEqual(len(self.my_map.tiles), self.my_map.size)
        [
            self.assertEqual(len(self.my_map.tiles[y]), self.my_map.size)
            for y in range(self.my_map.size)
        ]

        # there is an asteroids around the map
        self.assertEqual(self.my_map.empty_tiles, (self.map_size - 2)**2)

        for y in range(self.map_size):
            for x in range(self.map_size):
                pos = Position(x=x, y=y)
                self.assertFalse(self.my_map.is_out_of_bound(pos))

                if x == 0 or x == self.map_size - 1 or y == 0 or y == self.map_size - 1:
                    # check asteroids
                    self.assertFalse(self.my_map.is_empty(pos))
                    self.assertEqual(self.my_map.tiles[y][x],
                                     (GameMap.ASTEROIDS, None))
                    self.assertTrue(self.my_map.is_asteroids(pos))
                    self.assertEqual(self.my_map.get_tile(Position(x=x, y=y)),
                                     (GameMap.ASTEROIDS, None))
                else:
                    # must be empty
                    self.assertTrue(self.my_map.is_empty(pos))
                    self.assertFalse(self.my_map.is_asteroids(pos))
                    self.assertEqual(self.my_map.get_tile(Position(x=x, y=y)),
                                     (GameMap.EMPTY, None))
Пример #4
0
    def test_eq(self):
        """
        Tests that the __eq__ work
        """

        self.assertEqual(Position(3, 5), Position(3, 5))
        self.assertNotEqual(Position(4, 5), Position(5, 5))
Пример #5
0
    def test_with_direction(self):
        data = """
               WWWWWW
               W1  3W
               WD  DW
               WD  DW
               W4  2W
               WWWWWW\r\n
           """
        gc = GameConfig.from_str(data)

        self.assertEqual(
            gc.spawn_positions,
            [Position(1, 1),
             Position(4, 4),
             Position(4, 1),
             Position(1, 4)])
        self.assertEqual(
            gc.spawn_directions,
            [
                Direction(Direction.DOWN),
                Direction(Direction.UP),
                Direction(Direction.DOWN),
                Direction(Direction.UP)
            ],
        )
Пример #6
0
    def test_str(self):
        """
        Tests that __str__ work
        """

        self.assertEqual(Position(3, 5).__str__(), "[x: 3, y: 5]")

        self.assertEqual(Position(3, 5).__str__(), "[x: 3, y: 5]")
Пример #7
0
 def get_random_empty_position(self) -> Position:
     """
     Find a random starting position for a player
     """
     map_size = self.size
     pos = Position(x=random.randint(1, map_size - 1), y=random.randint(1, map_size - 1))
     while self.empty_tiles > 0 and not self.is_empty(pos):
         pos = Position(x=random.randint(1, map_size - 1), y=random.randint(1, map_size - 1))
     return pos
Пример #8
0
    def test_copy_create_new_position(self):
        """
        Tests that copy will create a new position
        """
        oldPosition = Position(3, 5)
        newPosition = oldPosition.copy()

        self.assertIsNot(oldPosition, newPosition)
        self.assertEqual(oldPosition, newPosition)
Пример #9
0
    def test_add(self):
        """
        Tests that the move method will move the position in the right direction
        """

        oldPosition = Position(3, 4)
        newPosition = oldPosition + (0, 1)

        self.assertIsNot(oldPosition, newPosition)
        self.assertEqual(Position(3, 5), newPosition)
Пример #10
0
    def test_is_out_of_bound(self):
        """
        Test that a position is out of bound for the current map
        """

        self.assertTrue(
            self.my_map.is_out_of_bound(Position(-self.map_size, 5)))
        self.assertTrue(self.my_map.is_out_of_bound(Position(self.map_size,
                                                             5)))
        self.assertTrue(
            self.my_map.is_out_of_bound(Position(5, -self.map_size)))
        self.assertTrue(self.my_map.is_out_of_bound(Position(5,
                                                             self.map_size)))
        self.assertTrue(
            self.my_map.is_out_of_bound(Position(self.map_size,
                                                 self.map_size)))
        self.assertTrue(
            self.my_map.is_out_of_bound(
                Position(-self.map_size, -self.map_size)))

        self.assertFalse(self.my_map.is_out_of_bound(Position(0, 0)))
        self.assertFalse(self.my_map.is_out_of_bound(Position(5, 5)))
        self.assertFalse(
            self.my_map.is_out_of_bound(
                Position(self.map_size - 1, self.map_size - 1)))
Пример #11
0
    def test_from_str(self):
        data = """
            WWWWW
            W!%$W
            W1 3W
            W4W2W
            WWWWW\r\n
        """
        gc = GameConfig.from_str(data)

        self.assertEqual(gc.game_map.size, 5)
        self.assertEqual(gc.game_map.get_tile(Position(1, 1)),
                         (GameMap.BLACK_HOLE, None))
        self.assertEqual(gc.game_map.get_tile(Position(2, 1)),
                         (GameMap.PLANET, None))
        self.assertEqual(gc.game_map.get_tile(Position(3, 1)),
                         (GameMap.BLITZIUM, None))
        self.assertEqual(gc.game_map.get_tile(Position(2, 2)),
                         (GameMap.EMPTY, None))
        self.assertEqual(gc.game_map.get_tile(Position(2, 3)),
                         (GameMap.ASTEROIDS, None))
        self.assertEqual(
            gc.spawn_positions,
            [Position(1, 2),
             Position(3, 3),
             Position(3, 2),
             Position(1, 3)])
Пример #12
0
 def test_dir_to_center(self):
     map_size = 5
     self.assertEqual(dir_to_center(Position(0, 0), map_size),
                      Direction.RIGHT)
     self.assertEqual(dir_to_center(Position(0, 1), map_size),
                      Direction.DOWN)
     self.assertEqual(dir_to_center(Position(map_size - 1, 0), map_size),
                      Direction.LEFT)
     self.assertEqual(
         dir_to_center(Position(map_size - 1, map_size - 2), map_size),
         Direction.UP)
Пример #13
0
    def test_cannot_overwrite_asteroids(self):
        # Ok to write an asteroids on an asteroids
        self.my_map.set_tile(Position(x=0, y=0), state=GameMap.ASTEROIDS)

        # Invalid to overwrite an asteroids with something else
        with self.assertRaises(InvalidStateException):
            self.my_map.set_tile(Position(x=0, y=0),
                                 state=GameMap.EMPTY,
                                 player_id=0)

        with self.assertRaises(InvalidStateException):
            self.my_map.set_tile(Position(x=0, y=0), state=GameMap.EMPTY)
Пример #14
0
    def clear_tile_owned_by(self, player_id: int) -> None:
        """
        Clear all tiles owned by the player_id; sets them to empty

        Parameters
        ----------
        player_id : int
            The player id
        """
        for y in range(len(self.tiles)):
            for x in range(len(self.tiles)):
                if self.get_owner(Position(x=x, y=y)) == player_id:
                    self.clear_tile(position=Position(x=x, y=y))
Пример #15
0
def flood(flood: List[List[int]], target: int, replacement: int) -> None:
    x_size = len(flood[0])
    y_size = len(flood)

    queue: SimpleQueue = SimpleQueue()
    queue.put(Position(0, 0))
    while not queue.empty():
        cur = queue.get()
        for _, delta in directions:
            sibblingX = cur.x + delta[0]
            sibblingY = cur.y + delta[1]
            if sibblingX >= 0 and sibblingX < x_size and sibblingY >= 0 and sibblingY < y_size:
                if flood[sibblingY][sibblingX] == target:
                    flood[sibblingY][sibblingX] = replacement
                    queue.put(Position(sibblingX, sibblingY))
Пример #16
0
def dict_to_game_map(data: List[List[str]]) -> GameMap:
    map_size = len(data)
    game_map = GameMap(map_size)

    for y in range(1, map_size - 1):
        for x in range(1, map_size - 1):
            splitted = data[y][x].split("-")
            tile = splitted[0]
            owner = None
            if len(splitted) > 1:
                owner = int(splitted[1])

            pos = Position(x, y)
            if tile == " ":
                game_map.set_tile(pos, GameMap.EMPTY, None)
            elif tile == "W":
                game_map.set_tile(pos, GameMap.ASTEROIDS, None)
            elif tile == "!":
                game_map.set_tile(pos, GameMap.BLACK_HOLE, None)
            elif tile == "$":
                game_map.set_tile(pos, GameMap.BLITZIUM, None)
            elif tile == "%":
                game_map.set_tile(pos, GameMap.PLANET, owner)
            elif tile == "C":
                game_map.set_tile(pos, GameMap.EMPTY, owner)

    return game_map
Пример #17
0
    def update_players_scores(self) -> None:
        # tiles count may become out of sync because a player might conquer someone else territory
        for player in self.players:
            player.stats.set_stat(PlayerStats.CONQUERED, 0)
            player.stats.set_stat(PlayerStats.PLANETS, 0)

        for x in range(0, self.game_map.size):
            for y in range(0, self.game_map.size):
                tile_state, player_id = self.game_map.get_tile(Position(x, y))

                if player_id is not None:
                    if tile_state == GameMap.PLANET:
                        self.players[
                            player_id].score += GameState.SCORE_CONQUERED_PLANET
                        self.players[player_id].stats.add_stat(
                            PlayerStats.PLANETS)
                    else:
                        self.players[
                            player_id].score += GameState.SCORE_CONQUERED

                    self.players[player_id].stats.add_stat(
                        PlayerStats.CONQUERED)

        for p in self.players:
            p.score += len(p.tail) * GameState.SCORE_TAIL
Пример #18
0
 def get_empty_tiles(self) -> List[Position]:
     empty = []
     for x in range(1, self.size - 1):
         for y in range(1, self.size - 1):
             if self.tiles[y][x] == GameMap.empty_tile:
                 empty.append(Position(x, y))
     return empty
Пример #19
0
def game_state_to_frame(player_id: int, state: GameState) -> np.array:
    size = state.game_map.size
    frame = np.zeros((size, size))

    for y in range(size):
        for x in range(size):
            tile_state, tile_owner = state.game_map.get_tile(Position(x, y))

            value = EMPTY
            if tile_state == GameMap.ASTEROIDS or tile_state == GameMap.BLACK_HOLE:
                value = ASTEROIDS_BH
            elif tile_state == GameMap.BLITZIUM:
                value = BLITZIUM
            elif tile_state == GameMap.PLANET and tile_owner != player_id:
                value = PLANETS

            if tile_owner is not None:
                if tile_owner == player_id:
                    value = CAPTURED_BY_PLAYER
                else:
                    value = CAPTURED_BY_OTHERS

            frame[y, x] = value

    for p in state.players:
        if p.id == player_id:
            payer_state_to_frame(p, frame, head=PLAYER_HEAD, tail=PLAYER_TAIL)
        else:
            payer_state_to_frame(p, frame, head=OTHERS_HEAD, tail=OTHERS_TAIL)

    return frame
Пример #20
0
 def count_tiles_owned_by(self, player_id: int) -> int:
     conquered = 0
     for y in range(len(self.tiles)):
         for x in range(len(self.tiles)):
             if self.get_owner(Position(x=x, y=y)) == player_id:
                 conquered += 1
     return conquered
Пример #21
0
    def test_init_with_values(self):
        """
        Tests that the position constructor saves to right values
        """

        position = Position(3, 4)
        self.assertEqual(position.x, 3)
        self.assertEqual(position.y, 4)
Пример #22
0
    def test_init_with_direction(self):
        game_map = GameMap(5)
        pos = Position(1, 1)
        ps = PlayerState(id=1,
                         name="dummy",
                         game_map=game_map,
                         position=pos,
                         direction=Direction(Direction.DOWN))

        self.assertEqual(ps.direction, Direction(Direction.DOWN))
Пример #23
0
 def test_skip_player_turn_if_killed(self):
     game = get_game()
     player = DummyPlayer(lambda x, y: (x, Action.TURN_LEFT))
     game.register_player(player)
     player.player_state.killed = True
     player.player_state.position = Position(0, 0)
     next_move = asyncio.run(game.request_next_move(player))
     self.assertEqual(next_move, None)
     self.assertEqual(player.player_state.position,
                      player.player_state.spawn_position)
Пример #24
0
    def test_invalid_set_title(self):
        pos = Position(x=1, y=1)

        # cannot have player id
        with self.assertRaises(InvalidStateException):
            self.my_map.set_tile(pos, state=GameMap.ASTEROIDS, player_id=1)
        with self.assertRaises(InvalidStateException):
            self.my_map.set_tile(pos, state=GameMap.BLITZIUM, player_id=1)
        with self.assertRaises(InvalidStateException):
            self.my_map.set_tile(pos, state=GameMap.BLACK_HOLE, player_id=1)
Пример #25
0
    def test_init(self):
        game_map = GameMap(5)
        pos = Position(1, 1)
        ps = PlayerState(id=1, name="dummy", game_map=game_map, position=pos)

        self.assertFalse(ps.killed)
        self.assertEqual(ps.score, 0)
        self.assertEqual(ps.spawn_position, pos)
        self.assertEqual(ps.position, pos)
        self.assertEqual(ps.tail, [ps.spawn_position])
        self.assertEqual(ps.direction, Direction.RIGHT)
        self.assertTrue(ps.game_map.is_conquered_by(pos, 1))
Пример #26
0
    def create_state(self):
        game_map = GameMap(21)
        game_state = GameState(game_map)
        p0 = game_state.add_player("0")
        p0.stats.kill_player("p1")
        p0.stats.killed_by_player("p2")
        p0.stats.add_stat(PlayerStats.SUICIDES)
        p0.stats.add_stat(PlayerStats.BLITZIUMS)
        p0.stats.add_stat(PlayerStats.CONQUERED)
        p0.tail = [Position(1, 2), Position(2, 3), Position(4, 5)]
        p0.history.append(
            HistoryItem(11, "message-11",
                        datetime.datetime(1900, 1, 1, 13, 14, 15, 555)))
        p0.history.append(
            HistoryItem(10, "message-10",
                        datetime.datetime(1900, 1, 1, 13, 14, 15, 444)))

        p1 = game_state.add_player("1")
        p1.stats.kill_player("p1")
        p1.stats.killed_by_player("p2")
        p1.stats.add_stat(PlayerStats.SUICIDES)
        p1.stats.add_stat(PlayerStats.BLITZIUMS)
        p1.stats.add_stat(PlayerStats.CONQUERED)
        p1.tail = [Position(1, 2), Position(2, 3), Position(4, 5)]
        p1.history.append(
            HistoryItem(11, "message-11",
                        datetime.datetime(1900, 1, 1, 13, 14, 15, 555)))
        p1.history.append(
            HistoryItem(10, "message-10",
                        datetime.datetime(1900, 1, 1, 13, 14, 15, 444)))

        return game_state
Пример #27
0
    def test_clear_tile_owned_by(self):
        """
        Tests that test_clear_tile_owned_by only clear tiles owned by the right player
        """
        self.my_map.set_tile(Position(5, 5), GameMap.PLANET, player_id=None)
        self.my_map.conquer_tile(Position(5, 5), player_id=1)
        self.my_map.conquer_tile(Position(5, 6), player_id=1)
        self.my_map.conquer_tile(Position(5, 7), player_id=1)
        self.my_map.conquer_tile(Position(1, 5), player_id=2)
        self.assertEqual(self.my_map.count_tiles_owned_by(player_id=1), 3)

        self.my_map.clear_tile_owned_by(player_id=1)
        self.assertEqual(self.my_map.count_tiles_owned_by(player_id=1), 0)

        self.assertFalse(self.my_map.is_empty(Position(5, 5)))
        self.assertEqual(self.my_map.get_tile(Position(5, 5)),
                         (GameMap.PLANET, None))
        self.assertTrue(self.my_map.is_empty(Position(7, 5)))

        self.assertEqual(self.my_map.get_tile(Position(1, 5)),
                         (GameMap.EMPTY, 2))
        self.assertEqual(self.my_map.get_owner(Position(1, 5)), 2)
Пример #28
0
    def test_send_winner_socket_closed(self):
        server = Mock()
        socket = AsyncMock()
        socket.send.side_effect = websockets.ConnectionClosed(0, "")
        viewer = SocketViewer(server, socket)
        viewer.logger = Mock()

        gs = GameState(GameMap(3))
        ps = PlayerState(1, "p1", gs.game_map, Position(1, 1))
        asyncio.run(viewer.send_winner(123, ps))

        viewer.logger.warning.assert_called_once()
        server.game.unregister_viewer.assert_called_once()
Пример #29
0
    def test_is_conquered_by(self):
        """
        Test that you can identify tiles owned by you
        """

        position = Position(1, 1)
        self.assertTrue(self.my_map.is_empty(position))
        self.assertFalse(self.my_map.is_conquered_by(position, player_id=1))

        self.my_map.conquer_tile(position, player_id=1)
        self.assertTrue(self.my_map.is_conquered_by(position, player_id=1))
        self.assertFalse(self.my_map.is_conquered_by(position, player_id=0))

        self.my_map.set_tile(position, GameMap.PLANET, player_id=None)
        self.my_map.conquer_tile(position, player_id=1)
        self.assertTrue(self.my_map.is_conquered_by(position, player_id=1))
        self.assertEqual(self.my_map.get_tile(position), (GameMap.PLANET, 1))

        with self.assertRaises(OutOfBoundExeption):
            self.my_map.is_conquered_by(Position(self.map_size + 10,
                                                 self.map_size + 10),
                                        player_id=0)
Пример #30
0
    def from_str(cls, data: str) -> "GameConfig":
        lines = data.strip().split("\n")

        map_size = len(lines)
        game_map = GameMap(map_size)

        spawn_positions = []
        spawn_directions = []
        spawn_direction_markers = []

        for y, line in enumerate(lines):
            line = line.strip()
            if len(line) != map_size:
                raise Exception(f"Map is not square! (line {y} as length {len(line)})")

            for x, tile in enumerate(line):
                pos = Position(x, y)
                if tile == GameMap.EMPTY:
                    game_map.set_tile(pos, GameMap.EMPTY, None)
                elif tile == GameMap.ASTEROIDS:
                    game_map.set_tile(pos, GameMap.ASTEROIDS, None)
                elif tile == GameMap.BLACK_HOLE:
                    game_map.set_tile(pos, GameMap.BLACK_HOLE, None)
                elif tile == GameMap.BLITZIUM:
                    game_map.set_tile(pos, GameMap.BLITZIUM, None)
                elif tile == GameMap.PLANET:
                    game_map.set_tile(pos, GameMap.PLANET, None)
                elif tile == GameMap.DIRECTION:
                    # Directions are meta information not visible on the map
                    game_map.set_tile(pos, GameMap.EMPTY, None)
                    spawn_direction_markers.append(pos)
                elif tile.isdigit():
                    player_id = int(tile)
                    spawn_positions.append((player_id, pos))
                else:
                    raise Exception(f"Invalid tile '{tile}' as position {pos}.")

        spawn_positions.sort()

        if len(spawn_direction_markers) > 0:
            # for each player we find the closest direction marker
            # this algorithm won't work if a direction marker is
            # close to 2 spawn_positions
            for player_id, spawn_position in spawn_positions:
                for direction_marker in spawn_direction_markers:
                    if spawn_position.is_next_to(direction_marker):
                        direction = spawn_position.direction_to(direction_marker)
                        spawn_directions.append(direction)

        return GameConfig(game_map, [p for i, p in spawn_positions], spawn_directions)