예제 #1
0
파일: utils.py 프로젝트: MrRobotik/dicewars
def area_descriptor(area: Area, board: Board):
    neighborhood = area.get_adjacent_areas()
    player_name = area.get_owner_name()
    enemy_areas = [
        adj for adj in neighborhood
        if board.get_area(adj).get_owner_name() != player_name
    ]
    owned_areas = [
        adj for adj in neighborhood
        if board.get_area(adj).get_owner_name() == player_name
    ]
    unique_enemies = {
        board.get_area(adj).get_owner_name()
        for adj in neighborhood
    }
    if player_name in unique_enemies:
        unique_enemies.remove(player_name)
    max_region_size = max(
        len(r) for r in board.get_players_regions(player_name))

    feature_vector = [
        survival_prob(area, board),
        rel_area_power(area, board),
        len(enemy_areas),
        len(owned_areas),
        len(unique_enemies), max_region_size / len(board.areas)
    ]
    return np.asarray(feature_vector, dtype=np.float32)
예제 #2
0
파일: utils.py 프로젝트: MrRobotik/dicewars
def game_descriptor(board: Board, player_name: int, players: list):
    areas = board.get_player_areas(player_name)
    regions = board.get_players_regions(player_name)
    border = board.get_player_border(player_name)
    max_region_size = max(len(r) for r in regions)
    rel_border_size_1 = len(border) / sum(
        len(board.get_player_border(name)) for name in players)
    rel_border_size_2 = sum(a.get_dice() for a in border) / sum(a.get_dice()
                                                                for a in areas)
    rel_area_size = len(areas) / sum(
        len(board.get_player_areas(name)) for name in players)

    best_border = []
    for r in regions:
        if len(r) == max_region_size:
            for area in map(lambda a: board.get_area(a), r):
                if board.is_at_border(area):
                    best_border.append(area)

    feature_vector = [
        max_region_size / len(board.areas), rel_border_size_1,
        rel_border_size_2, rel_area_size,
        np.mean([survival_prob(a, board) for a in best_border]),
        np.mean([rel_area_power(a, board) for a in areas])
    ]
    return np.asarray(feature_vector, dtype=np.float32)
    def _heuristic(self, players: List[int], board: Board) -> Dict[int, float]:
        """
        Computes the heuristic function for all the given players.

        :param players: Names of players.
        :param board: The game board.
        :return: A dictionary where keys are names of given players and values
                 are values of the heuristic function for these players in a
                 current game board.
        """
        h = {}
        for player in players:
            h[player] = board.get_player_dice(player)

            players_regions = board.get_players_regions(player)
            players_regions_sizes = []
            for region in players_regions:
                region_size = len(region)
                h[player] += self.__REG_HEURISTIC_WEIGHT * region_size
                players_regions_sizes.append(region_size)

            h[player] += \
                self.__LARGEST_REG_HEURISTIC_WEIGHT * max(players_regions_sizes)

        return h
예제 #4
0
    def __largest_region(player_name: int, board: Board) -> List[int]:
        """
        Returns the largest region of a given player.

        :param player_name: A name (ID) of the associated player.
        :param board: The game board.
        :return: The largest region of a given player. (A list of area
                 names (IDs) in the largest region.)
        """
        players_regions = board.get_players_regions(player_name)
        max_region_size = max(len(r) for r in players_regions)

        return [r for r in players_regions if len(r) == max_region_size][0]
예제 #5
0
def player_heuristic(board: Board, player_name: int) -> int:
    """Výpočet heuristiky pro hráče podle aktuálního stavu herní plochy.
    koeficient = počet_polí_hlavního_území

    Args
    ----
        board (Board): Aktuální stav herní plochy
        player_name (int): Jméno hráče

    Returns
    -------
        int: Výsledná hodnota heuristiky. Větší znamená lepší
    """

    score = 0
    regions = board.get_players_regions(player_name)
    for region in regions:
        score = max(score, len(region))
    return score
예제 #6
0
def add_dice_to_player(board: Board, player_name: int):
    """Vytvoří dočasné herní pole s náhodně přidělenými kostkami pro vybraného
    hráče. Základní logika předělování kostek je převzatá z implemenetace hry
    viz dicewars/server/game.py line:230.

    Funkce se používá stejně jako funkce simulate_battle.

    Args
    ----
        board (Board): Aktuální stav herního pole
        player_name (int): Jméno hráče, kterému se mají přiřadit kostky
    """

    affected_areas: Dict[int, int] = {}
    dice = 0
    regions = board.get_players_regions(player_name)
    for region in regions:
        dice = max(dice, len(region))

    areas: List[Area] = []
    for area in board.get_player_areas(player_name):
        areas.append(area)

    if dice > 64:
        dice = 64

    while dice and areas:
        area = random.choice(areas)
        if area.dice >= 8:
            areas.remove(area)
        else:
            if area.name not in affected_areas:
                affected_areas[area.name] = area.dice
            area.dice += 1
            dice -= 1

    try:
        yield
    finally:
        # Vrátit herní pole do původního stavu
        for name in affected_areas:
            board.get_area(name).dice = affected_areas[name]
예제 #7
0
def add_dice_to_player_worst_case(board: Board, player_name: int, is_yourself: bool, logger):
    affected_areas: Dict[int, int] = {}
    dice = 0
    regions = board.get_players_regions(player_name)
    for region in regions:
        dice = max(dice, len(region))

    if is_yourself:
        areas = board.get_player_areas(player_name)
        b_a = board.get_player_border(player_name)
        areas = list(set(areas)-set(b_a))
        if areas is None:
            areas = b_a
    else:
        areas =  board.get_player_border(player_name)

    arr = [a.get_name() for a in areas]
    logger.info("PLayer: {} with areas: {}".format(player_name, arr))

    if dice > 64:
        dice = 64

    while dice and areas:
        if is_yourself:
            area = random.choice(areas)
            while area.dice < 8:
                area.dice += 1
                dice -= 1
        else:
            area = areas.pop(0)
            areas.append(area)

        if area.dice >= 8:
            areas.remove(area)
        elif not is_yourself:
            if area.name not in affected_areas:
                affected_areas[area.name] = area.dice
            area.dice += 1
            dice -= 1

    if dice > 0:
        if is_yourself:
            areas = board.get_player_border(player_name)
        else:
            areas = board.get_player_areas(player_name)
        while dice and areas:
            area = random.choice(areas)

            if area.dice >= 8:
                areas.remove(area)
            else:
                if area.name not in affected_areas:
                    affected_areas[area.name] = area.dice
                area.dice += 1
                dice -= 1

    try:
        yield
    finally:
        # Vrátit herní pole do původního stavu
        for name in affected_areas:
            board.get_area(name).dice = affected_areas[name]