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)
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
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]
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
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]
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]