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 path_heuristics(board: Board, path: list) -> float: """ Heuristika = součet všech dílčích heuristik v cestě """ if len(path) < 2: return 0 with simulate_battle(board.get_area(path[0]), board.get_area(path[1])): h = path_heuristics(board, path[1:]) h += battle_heuristic(board, board.get_area(path[0]), board.get_area(path[1])) return h
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 survival_prob(target: Area, board: Board): prob = 1. for adj in target.get_adjacent_areas(): source = board.get_area(adj) if source.get_owner_name() == target.get_owner_name( ) or not source.can_attack(): continue prob *= 1. - ATTACK_SUCC_PROBS[source.get_dice()][target.get_dice()] return prob
def get_attackable(board: Board, active_area: Area): neighbors = active_area.get_adjacent_areas() attackable = [] for nb in neighbors: a = board.get_area(nb) if active_area.get_owner_name() != a.get_owner_name(): attackable.append(a) return attackable
def possible_attacks(board: Board, player_name: int): for source in board.get_player_border(player_name): if not source.can_attack(): continue for adj in source.get_adjacent_areas(): target = board.get_area(adj) if target.get_owner_name() != player_name: succ_prob = ATTACK_SUCC_PROBS[source.get_dice()][ target.get_dice()] yield source, target, succ_prob
def rel_area_power(area: Area, board: Board): player_power = area.get_dice() total_power = player_power for adj in area.get_adjacent_areas(): adj_area = board.get_area(adj) dice = adj_area.get_dice() if adj_area.get_owner_name() == area.get_owner_name(): player_power += dice total_power += dice return player_power / total_power
def possible_attacks(board: Board, player_name: int) -> Iterator[Tuple[int, int]]: for area in board.get_player_border(player_name): if not area.can_attack(): continue neighbours = area.get_adjacent_areas() for adj in neighbours: adjacent_area = board.get_area(adj) if adjacent_area.get_owner_name() != player_name: yield (area, adjacent_area)
def __perform_atack(board: Board, a_name: int, b_name: int) -> None: """ Performes a successful atack. :param board: The game board. :param a_name: A name of an atacker area. :param b_name: A name of a defender area. """ a = board.get_area(a_name) b = board.get_area(b_name) b.set_dice(a.get_dice() - 1) a.set_dice(1) b.set_owner(a_name)
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]