Пример #1
0
def game_instance():
    game_map = MapGenerator(5, 5).generate(GAME_MAP)

    # Initialize game engine
    game_engine = GameEngine(game_map)

    map_proxy = MapProxy(game_engine)
    game_object_proxy = GameObjectProxy(game_engine)
    game_control_proxy = GameControlProxy(game_engine)
    game_uncertainty_proxy = GameUncertaintyProxy(game_engine)

    # Register defender
    defender = Player(map_proxy, game_object_proxy, game_control_proxy, game_uncertainty_proxy)
    game_engine.register_player(defender, PlayerResources(1000, 10), [])

    # Register attacker
    attacker = AIPlayer(map_proxy, game_object_proxy, game_control_proxy, game_uncertainty_proxy)
    game_engine.register_player(attacker, PlayerResources(200, 0, 0), [])

    game_engine.start(500)

    game_engine.spawn_unit(SpawnInformation(defender, GameObjectType.BASE, OffsetPosition(0, 0), [], []))
    game_engine.spawn_unit(SpawnInformation(attacker, GameObjectType.DEMON, OffsetPosition(0, -2), [], []))
    game_engine.spawn_unit(SpawnInformation(attacker, GameObjectType.DEMON, OffsetPosition(-1, -1), [], []))

    attacker.initialize()

    return map_proxy, game_object_proxy, game_control_proxy, game_uncertainty_proxy, defender, attacker, game_engine
Пример #2
0
 def pl(self):
     print("FUUUCK")
     pos = OffsetPosition(-3, -4).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.ENT, pos, [], []))
     pos = OffsetPosition(-4, -3).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.ENT, pos, [], []))
Пример #3
0
    def __river_start_position(self) -> Position:
        """ Get river start position """
        left_bottom_corner = OffsetPosition(-self.__horizontal_radius,
                                            self.__vertical_radius)
        right_bottom_corner = OffsetPosition(self.__horizontal_radius,
                                             self.__vertical_radius)

        while True:
            starting_position = self.__pick_random_position(
                self.__border_tiles)

            if starting_position != left_bottom_corner and starting_position != right_bottom_corner:
                break

        return starting_position
Пример #4
0
 def build_base(self, position_q: int, position_r: int):
     Logger.log('Building base')
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player,
                          GameObjectType.BASE,
                          OffsetPosition(int(position_q), int(position_r)),
                          [], []))
def test_spawn_different_role(game_control_proxy, defender):
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.DEMON,
                              OffsetPosition(1, 1), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'Attempt to spawn unit of different role!' in str(exc.value)
def test_spawn_on_edge(game_control_proxy, defender):
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.ARCHER,
                              OffsetPosition(-1, -2), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'Cannot spawn unit defender unit on the map edge.' in str(exc.value)
def test_spawn_second_base(game_control_proxy, defender):
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.BASE,
                              OffsetPosition(1, 1), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'You cannot spawn additional base!' in str(exc.value)
Пример #8
0
    def __init__(self, width: int, height: int, seed: int = None):
        """
        :param width: - width of the map (must be ood number)
        :param height: - height of the map (must be odd number)
        :param seed: - random seed for generating map
        """
        self.__width = width
        self.__height = height

        self.__vertical_radius = (height - 1) // 2
        self.__horizontal_radius = (width - 1) // 2

        self.__game_map = GameMap(width, height)

        self.__border_tiles = self.__game_map.border_tiles

        self.__initialize_generator_config()

        if not seed:
            seed = Config.MAP_RANDOM_SEED

        if not seed:
            seed = int.from_bytes(os.urandom(50), 'big')
            Config.MAP_RANDOM_SEED = seed

        random.seed(seed)

        self.__base_random_list = self.create_base_random_list()

        for i in range(-self.__vertical_radius, self.__vertical_radius + 1):
            for j in range(-self.__horizontal_radius,
                           self.__horizontal_radius + 1):
                self.__game_map.set_tile(OffsetPosition(i, j), Field())
def test_spawn_unit_out_of_map(game_control_proxy, defender):
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.ARCHER,
                              OffsetPosition(0, -5), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'Position is not on the map!' in str(exc.value)
def test_spawn_unit_not_visible_tile(game_control_proxy, defender):
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.ARCHER,
                              OffsetPosition(0, -2), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'Attempt to spawn unit at not visible tile!' in str(exc.value)
Пример #11
0
 def tiles(self):
     """ Iterator for all map tiles """
     for y in range(-self.__horizontal_radius,
                    self.__horizontal_radius + 1):
         for x in range(-self.__vertical_radius,
                        self.__vertical_radius + 1):
             yield OffsetPosition(y, x)
Пример #12
0
    def border_tiles(self) -> Set[Position]:
        """
        Retrieves set of tiles on the edge of game map

        :return: Set of border tiles
        """
        border_tiles = set()
        for x in range(-self.__horizontal_radius,
                       self.__horizontal_radius + 1):
            border_tiles.add(OffsetPosition(x, -self.__vertical_radius))
            border_tiles.add(OffsetPosition(x, self.__vertical_radius))

        for y in range(-self.__vertical_radius, self.__vertical_radius + 1):
            border_tiles.add(OffsetPosition(-self.__horizontal_radius, y))
            border_tiles.add(OffsetPosition(self.__horizontal_radius, y))

        return border_tiles
def test_spawn_insufficient_resources(game_control_proxy, defender):
    flexmock(Ent).should_receive('cost').and_return(5000)
    with pytest.raises(IllegalActionException) as exc:
        si = SpawnInformation(defender, GameObjectType.ENT,
                              OffsetPosition(1, 1), [], [])
        game_control_proxy.spawn_unit(si)

    assert 'Insufficient resources!' in str(exc.value)
Пример #14
0
 def __generate_tiles(self):
     """ Generate all tiles (without water) """
     for i in range(-self.__vertical_radius, self.__vertical_radius + 1):
         for j in range(-self.__horizontal_radius,
                        self.__horizontal_radius + 1):
             position = OffsetPosition(i, j)
             if self.__game_map[position].terrain_type != TerrainType.RIVER:
                 self.__game_map.set_tile(
                     position, self.get_random_terrain_type(position))
Пример #15
0
def test_compute_accessible_tiles(map_proxy):
    assert map_proxy.compute_accessible_tiles(OffsetPosition(0, 0), 2) == {
        OffsetPosition(-1, -2): 0,
        OffsetPosition(-1, -1): 1,
        OffsetPosition(1, -1): 1,
        OffsetPosition(1, 0): 0,
        OffsetPosition(0, 1): 0,
        OffsetPosition(0, 0): 2,
    }
Пример #16
0
    def free_sides(self):
        free_pos = set()

        pos = OffsetPosition(-1, -5).offset
        if not self.map_proxy.is_position_occupied(pos):
            free_pos.add(pos)

        pos = OffsetPosition(-2, -5).offset
        if not self.map_proxy.is_position_occupied(pos):
            free_pos.add(pos)

        pos = OffsetPosition(-5, -3).offset
        if not self.map_proxy.is_position_occupied(pos):
            free_pos.add(pos)

        pos = OffsetPosition(-5, -2).offset
        if not self.map_proxy.is_position_occupied(pos):
            free_pos.add(pos)

        free_pos.intersection_update(self.map_proxy.get_player_visible_tiles())
        return free_pos
Пример #17
0
 def build_base(self, x, y):
     # Custom log messages
     n = FilterFactory().attack_filter(AttackNearestFilter)
     Logger.log('Building base')
     base_pos = OffsetPosition(x, y).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.BASE, base_pos, [n],
                          []))
     base_pos = OffsetPosition(-5, -5).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.MAGICIAN, base_pos,
                          [n], []))
     base_pos = OffsetPosition(-4, -5).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.MAGICIAN, base_pos,
                          [n], []))
     base_pos = OffsetPosition(-5, -4).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.MAGICIAN, base_pos,
                          [n], []))
     base_pos = OffsetPosition(-4, -3).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.ARCHER, base_pos, [n],
                          []))
     base_pos = OffsetPosition(-3, -5).offset
     self.game_control_proxy.spawn_unit(
         SpawnInformation(self.player, GameObjectType.ARCHER, base_pos, [n],
                          []))
Пример #18
0
    def __init__(self,
                 width: int,
                 height: int,
                 tiles: List[List[Union['TerrainType', str]]] = None):
        self.__size = (width, height)
        if width % 2 == 0 or height % 2 == 0:
            raise IllegalArgumentException('Map size must be odd numbers')

        if width < 3:
            raise IllegalArgumentException('Map width must be greater than 2')

        if height < 3:
            raise IllegalArgumentException('Map height must be greater than 2')

        self.__width = width
        self.__height = height

        self.__vertical_radius = (height - 1) // 2
        self.__horizontal_radius = (width - 1) // 2

        self.__visible_tiles_cache = {}

        self.__tiles = []  # type: List[List[Union[Terrain,None]]]
        for i in range(height):
            self.__tiles.append([])
            for j in range(width):
                self.__tiles[i].append(None)

        if tiles:
            for y, terrain_list in enumerate(tiles):
                for x, terrain_type in enumerate(terrain_list):
                    position = OffsetPosition(x - self.__horizontal_radius,
                                              y - self.__vertical_radius)
                    if type(terrain_type) is TerrainType:
                        self.set_tile(position, terrain_type.value)
                    elif type(terrain_type) is str:
                        _terrain_type = TerrainType.from_char(
                            terrain_type).value
                        if _terrain_type is None:
                            raise IllegalArgumentException(
                                'Invalid tile character {}'.format(
                                    terrain_type))
                        self.set_tile(
                            position,
                            TerrainType.from_char(terrain_type).value)
                    else:
                        raise IllegalArgumentException(
                            'Map tiles could be TerrainType enum or string representation!'
                        )
Пример #19
0
    def build_base(self, position_q: int, position_r: int):
        # Custom log messages
        Logger.log('Building base')

        empty_filter = FilterFactory().attack_filter(EmptyAttackFilter)
        dummy_filter = FilterFactory().attack_filter(DummyAttackFilter,
                                                     'Base attacking')

        # Create instance of default filter
        strongest_filter = FilterFactory().attack_filter(AttackStrongestFilter)

        self.game_control_proxy.spawn_unit(
            SpawnInformation(self.player, GameObjectType.BASE,
                             OffsetPosition(int(position_q), int(position_r)),
                             [], []))
Пример #20
0
class EvenOffsetDirection(Enum):
    """
        Direction of neighbours on hexagon grid defined with Offset position
        Be careful that directions are different for odd and even columns
    """
    UPPER = OffsetPosition(0, -1)
    RIGHT_UPPER = OffsetPosition(+1, 0)
    RIGHT_LOWER = OffsetPosition(+1, +1)
    LOWER = OffsetPosition(0, 1)
    LEFT_LOWER = OffsetPosition(-1, 0)
    LEFT_UPPER = OffsetPosition(-1, 0)
Пример #21
0
    def __create_linked_list(self):
        """ Create linked list for iterating over edge tiles """

        # In the corners, there are more than one neighbor. Precedence list will chose correct one
        precedence = {
            OffsetPosition(self.__game_map.horizontal_radius,
                           self.__game_map.vertical_radius),
            OffsetPosition(-self.__game_map.horizontal_radius,
                           self.__game_map.vertical_radius),
            OffsetPosition(self.__game_map.horizontal_radius,
                           -self.__game_map.vertical_radius),
            OffsetPosition(-self.__game_map.horizontal_radius,
                           -self.__game_map.vertical_radius),
            OffsetPosition(-self.__game_map.horizontal_radius + 2,
                           -self.__game_map.vertical_radius)
        }

        first = OffsetPosition(-self.__game_map.horizontal_radius,
                               -self.__game_map.vertical_radius)
        second = OffsetPosition(-self.__game_map.horizontal_radius + 1,
                                -self.__game_map.vertical_radius)
        self.__border_tiles.push_back(first)
        self.__border_tiles.push_back(second)

        tiles = self.__game_map.border_tiles
        tiles.remove(first)
        tiles.remove(second)

        current = self.__border_tiles.head.value
        while tiles:
            _next_set = set(current.get_all_neighbours()).intersection(tiles)
            if len(_next_set) > 1:
                _next_set = _next_set.intersection(precedence)

            _next = _next_set.pop()

            current = _next
            self.__border_tiles.push_back(_next)
            tiles.remove(_next)

        self.__border_tiles.head.next = self.__border_tiles.tail
        self.__border_tiles.tail.previous = self.__border_tiles.head
Пример #22
0
    def found_good(self):
        inner = self.map_proxy.get_inner_tiles()
        border = self.map_proxy.get_border_tiles()
        ban = set()
        ban.update(border)
        for x in border:
            a = x.get_all_neighbours()
            for z in a:
                ban.add(z)
        for pos in inner:
            if self.map_proxy.get_terrain_type(
                    pos).name == "FOREST" or self.map_proxy.get_terrain_type(
                        pos).name == "HILL" or self.map_proxy.get_terrain_type(
                            pos).name == "VILLAGE" and pos not in ban:
                z = pos.get_all_neighbours()
                flag = True
                for a in z:
                    if a in border:
                        flag = False
                if flag:
                    return pos.offset

        return OffsetPosition(0, 0).offset
Пример #23
0
 def list_positions_first_round(self):
     if not self.map_proxy.player_have_base(self.player):
         return None
     base_position = self.map_proxy.get_bases_positions().pop()
     positions_first_round = []
     positions_first_round.append(
         OffsetPosition(base_position.offset.q, base_position.offset.r - 1))
     positions_first_round.append(
         OffsetPosition(base_position.offset.q + 1, base_position.offset.r))
     positions_first_round.append(
         OffsetPosition(base_position.offset.q + 1,
                        base_position.offset.r + 1))
     positions_first_round.append(
         OffsetPosition(base_position.offset.q, base_position.offset.r + 1))
     positions_first_round.append(
         OffsetPosition(base_position.offset.q - 1,
                        base_position.offset.r + 1))
     positions_first_round.append(
         OffsetPosition(base_position.offset.q - 1, base_position.offset.r))
     return positions_first_round
Пример #24
0
    def appropriate_positions_first_round(self, coordinate):
        if not self.map_proxy.player_have_base(self.player):
            return []
        base_position = self.map_proxy.get_bases_positions().pop()
        all_positions = self.base_neighbours()
        visible_positions = self.map_proxy.get_player_visible_tiles()
        border_positions = self.map_proxy.get_border_tiles()

        res = []
        if coordinate == 'N':
            pos = OffsetPosition(int(base_position.offset.q),
                                 int(base_position.offset.r - 1))
            if pos in all_positions and pos in visible_positions and pos not in border_positions:
                res.append(pos)
        elif coordinate == 'S':
            pos = OffsetPosition(int(base_position.offset.q),
                                 int(base_position.offset.r + 1))
            if pos in all_positions and pos in visible_positions and pos not in border_positions:
                res.append(pos)
        elif coordinate == 'W':
            pos = [
                OffsetPosition(int(base_position.offset.q - 1),
                               int(base_position.offset.r - 1)),
                OffsetPosition(int(base_position.offset.q - 1),
                               int(base_position.offset.r + 1))
            ]
            for p in pos:
                if p in all_positions and p in visible_positions and p not in border_positions:
                    res.append(p)
        else:
            pos = [
                OffsetPosition(int(base_position.offset.q + 1),
                               int(base_position.offset.r - 1)),
                OffsetPosition(int(base_position.offset.q + 1),
                               int(base_position.offset.r + 1))
            ]
            for p in pos:
                if p in all_positions and p in visible_positions and p not in border_positions:
                    res.append(p)
        return res
Пример #25
0
 def actual_tiles_for_attack(self):
     return [
         OffsetPosition(0, 2),
         OffsetPosition(0, -2),
         OffsetPosition(2, 0),
         OffsetPosition(-2, 0),
         OffsetPosition(2, 1),
         OffsetPosition(-2, -1),
         OffsetPosition(1, 2),
         OffsetPosition(-1, -2),
         OffsetPosition(-1, 2),
         OffsetPosition(1, -2),
         OffsetPosition(-2, 1),
         OffsetPosition(2, -1),
         OffsetPosition(1, 1),
         OffsetPosition(-1, 1)
     ]
Пример #26
0
 def get_number_of_neighbours(self):
     return len([
         x for x in OffsetPosition(0, 0).get_all_neighbours()
         if self.map_proxy.is_position_occupied(x)
     ])
Пример #27
0
def test_get_player_visible_tiles(map_proxy):
    assert map_proxy.get_player_visible_tiles() == {
        OffsetPosition(-2, -1),
        OffsetPosition(-1, -2),
        OffsetPosition(-2, 0),
        OffsetPosition(-1, -1),
        OffsetPosition(0, -1),
        OffsetPosition(1, -2),
        OffsetPosition(-1, 0),
        OffsetPosition(0, 0),
        OffsetPosition(1, -1),
        OffsetPosition(2, -1),
        OffsetPosition(-1, 1),
        OffsetPosition(0, 1),
        OffsetPosition(1, 0),
        OffsetPosition(2, 0),
        OffsetPosition(0, 2),
        OffsetPosition(1, 1),
        OffsetPosition(2, 1),
    }
Пример #28
0
def test_compute_visible_tiles(map_proxy):
    assert map_proxy.compute_visible_tiles(OffsetPosition(0, 0), 2) == {
        OffsetPosition(-2, -1),
        OffsetPosition(-1, -2),
        OffsetPosition(-2, 0),
        OffsetPosition(-1, -1),
        OffsetPosition(0, -1),
        OffsetPosition(1, -2),
        OffsetPosition(-1, 0),
        OffsetPosition(0, 0),
        OffsetPosition(1, -1),
        OffsetPosition(2, -1),
        OffsetPosition(-1, 1),
        OffsetPosition(0, 1),
        OffsetPosition(1, 0),
        OffsetPosition(2, 0),
        OffsetPosition(0, 2),
        OffsetPosition(1, 1),
        OffsetPosition(2, 1),
    }
Пример #29
0
    def free_tile(self, x):
        base_q = self.map_proxy.get_bases_positions().pop().offset.q
        base_r = self.map_proxy.get_bases_positions().pop().offset.r
        pos = OffsetPosition
        if x == "1":
            pos = OffsetPosition(base_q - 1, base_r - 1)
        if x == "2":
            pos = OffsetPosition(base_q, base_r - 1)
        if x == "3":
            pos = OffsetPosition(base_q + 1, base_r - 1)
        if x == "4":
            pos = OffsetPosition(base_q + 1, base_r)
        if x == "5":
            pos = OffsetPosition(base_q, base_r + 1)
        if x == "6":
            pos = OffsetPosition(base_q - 1, base_r)

        if x == "7":
            pos = OffsetPosition(base_q - 2, base_r - 1)
        if x == "8":
            pos = OffsetPosition(base_q + 2, base_r - 1)
        if x == "9":
            pos = OffsetPosition(base_q - 2, base_r + 1)
        if x == "10":
            pos = OffsetPosition(base_q + 2, base_r + 1)

        if x == "11":
            pos = OffsetPosition(base_q, base_r + 2)
        if x == "12":
            pos = OffsetPosition(base_q, base_r - 2)
        if x == "13":
            pos = OffsetPosition(base_q + 2, base_r)
        if x == "14":
            pos = OffsetPosition(base_q - 2, base_r)

        if x == "15":
            pos = OffsetPosition(base_q + 1, base_r + 2)
        if x == "16":
            pos = OffsetPosition(base_q + 1, base_r - 2)
        if x == "17":
            pos = OffsetPosition(base_q - 1, base_r + 2)
        if x == "18":
            pos = OffsetPosition(base_q - 1, base_r - 2)
        print("===================")
        print(pos)
        print(x)
        print(self.map_proxy.get_bases_positions().pop())
        print("===================")
        visible = self.map_proxy.get_player_visible_tiles()
        border = self.map_proxy.get_border_tiles()
        if not self.map_proxy.is_position_occupied(pos) and pos in visible\
                and pos not in border and self.map_proxy.is_position_on_map(pos):
            return pos
Пример #30
0
    def __generate_river(self):
        """ Generate rivver tiles. There will be only one river with starting and ending at the map edge"""
        def filter_river_neighbour(position, ancestor):
            _neighbours = [
                self.__game_map[x].terrain_type
                for x in self.__game_map.filter_positions_on_map(
                    position.get_all_neighbours()) if ancestor != x
            ]

            if TerrainType.RIVER in _neighbours:
                return False

            return True

        if random.random() < self.river_prob:
            current = self.__river_start_position()
            river_length = 1
            self.__game_map.set_tile(current, River())

            while True:
                # Filter neighbours on map
                neighbours = self.__game_map.filter_positions_on_map(
                    current.get_all_neighbours())
                # Filter neighbours which are not RIVER
                neighbours = [
                    x for x in neighbours
                    if self.__game_map[x].terrain_type != TerrainType.RIVER
                ]
                # Filter neighbours which are have not river as neighbour
                neighbours = [
                    x for x in neighbours
                    if filter_river_neighbour(x, current)
                ]
                # Filter border tiles under size factor
                if river_length < 3:
                    neighbours = [
                        x for x in neighbours
                        if not self.__game_map.position_on_edge(x)
                    ]

                neighbours.sort(key=lambda x: (x.length(
                ) + 1 if self.__game_map.position_on_edge(x) else 0))
                if neighbours:
                    for i in range(6):
                        neighbours.append(neighbours[0])

                # If cannot continue generate new river
                if not neighbours:
                    for i in range(-self.__vertical_radius,
                                   self.__vertical_radius + 1):
                        for j in range(-self.__horizontal_radius,
                                       self.__horizontal_radius + 1):
                            self.__game_map.set_tile(OffsetPosition(i, j),
                                                     Field())
                    self.__generate_river()
                    break

                neighbour = random.choice(neighbours)
                self.__game_map.set_tile(neighbour, River())
                if self.__game_map.position_on_edge(neighbour):
                    break
                else:
                    current = neighbour
                    river_length += 1