Esempio n. 1
0
def find_systems_with_min_jumps_between(num_systems, systems_pool, min_jumps):
    """
    Find requested number of systems out of a pool that are at least a specified number of jumps apart.
    """
    # make several tries to get the requested number of systems
    attempts = min(100, len(systems_pool))
    while attempts > 0:
        attempts -= 1
        # shuffle our pool of systems so each try the candidates are tried in different order
        # (otherwise each try would yield the same result, which would make trying several times kind of pointless...)
        random.shuffle(systems_pool)
        # try to find systems that meet our condition until we either have the requested number
        # or we have tried all systems in our pool
        accepted = []
        for candidate in systems_pool:
            # check if our candidate is at least min_jumps away from all other systems we already found
            if all(
                    fo.jump_distance(candidate, system) >= min_jumps
                    for system in accepted):
                # if yes, add the candidate to the list of accepted systems
                accepted.append(candidate)
                # if we have the requested number of systems, we can stop and return the systems we found
                if len(accepted) >= num_systems:
                    return accepted
    # all tries failed, return an empty list to indicate failure
    return []
Esempio n. 2
0
def is_too_close_to_empire_home_systems(system, home_systems):
    """
    Checks if a system is too close to the player home systems.

    Player home systems should be at least 2 jumps away.
    """
    for home_system in home_systems:
        if fo.jump_distance(system, home_system) < 2:
            return True
    return False
Esempio n. 3
0
def is_too_close_to_empire_home_systems(system, home_systems):
    """
    Checks if a system is too close to the player home systems.

    Player home systems should be at least 2 jumps away.
    """
    for home_system in home_systems:
        if fo.jump_distance(system, home_system) < 2:
            return True
    return False
Esempio n. 4
0
def systems_min_jumps_away_from(systems_pool, min_jumps, chosen_systems):
    """
    Generator that returns systems randomly picked from a pool that are at least a certain jump distance away
    from the group systems listed in chosen_systems.
    """
    # on generator initialization shuffle our pool of systems to randomize the order in which the systems are returned
    random.shuffle(systems_pool)
    # return systems that meet our condition until we have exhausted our pool
    for candidate in systems_pool:
        # check if our candidate is at least the specified min jump distance away from the systems in chosen_systems
        # if yes, return candidate, otherwise continue with next candidate
        if all(fo.jump_distance(candidate, system) >= min_jumps for system in chosen_systems):
            yield candidate
Esempio n. 5
0
def systems_min_jumps_away_from(systems_pool, min_jumps, chosen_systems):
    """
    Generator that returns systems randomly picked from a pool that are at least a certain jump distance away
    from the group systems listed in chosen_systems.
    """
    # on generator initialization shuffle our pool of systems to randomize the order in which the systems are returned
    random.shuffle(systems_pool)
    # return systems that meet our condition until we have exhausted our pool
    for candidate in systems_pool:
        # check if our candidate is at least the specified min jump distance away from the systems in chosen_systems
        # if yes, return candidate, otherwise continue with next candidate
        if all(fo.jump_distance(candidate, system) >= min_jumps for system in chosen_systems):
            yield candidate
Esempio n. 6
0
def place_teams_layout(layout: Dict[int, List[int]], cores: Dict[int, int],
                       placement_teams: List[int]) -> Dict[int, int]:
    """
    Place teams on home systems layout.
    Returns map from home system to team.
    """
    # set team cores
    left_home_systems = set(layout.keys())
    result = {}
    for team, hs in cores.items():
        result[hs] = team
        left_home_systems.remove(hs)
    # for each team search for home system
    for team in placement_teams:
        # search such home system
        # 1. with maximum same team neighbors
        choose_hs = set()
        neighbors_count = None
        for hs in left_home_systems:
            cnt = len([n for n in layout[hs] if result.get(n, -1) == team])
            if neighbors_count is None or cnt > neighbors_count:
                choose_hs = {hs}
                neighbors_count = cnt
            elif cnt == neighbors_count:
                choose_hs.add(hs)

        # 2. with maximum jump distance from other teams
        if len(choose_hs) > 1:
            choose_hs2 = set()
            max_dist_to_enemy = None
            for hs in choose_hs:
                dist_to_enemy = None
                for hs2, team2 in result.items():
                    if team2 != team:
                        dist = fo.jump_distance(hs, hs2)
                        if dist_to_enemy is None or dist < dist_to_enemy:
                            dist_to_enemy = dist
                if max_dist_to_enemy is None or dist_to_enemy > max_dist_to_enemy:
                    max_dist_to_enemy = dist_to_enemy
                    choose_hs2 = {hs}
                elif dist_to_enemy == max_dist_to_enemy:
                    choose_hs2.add(hs)
            choose_hs = choose_hs2

        if choose_hs:
            hs = choose_hs.pop()
            result[hs] = team
            left_home_systems.remove(hs)
    return result.items()
Esempio n. 7
0
def home_system_layout(home_systems, systems):
    """
    Home systems layout generation to place teams.
    Returns map from home system to neighbor home systems.
    """
    # for each system found nearest home systems
    # maybe multiple if home worlds placed on the same jump distnace
    system_hs = {}
    for system in systems:
        nearest_hs = set()
        nearest_dist = None
        for hs in home_systems:
            dist = fo.jump_distance(system, hs)
            if nearest_dist is None or nearest_dist > dist:
                nearest_dist = dist
                nearest_hs = {hs}
            elif nearest_dist == dist:
                nearest_hs.add(hs)
        system_hs[system] = nearest_hs

    # homeworld is connected to the other
    # if both are nearest for some system
    # if each of them is nearest for systems on the starline ends
    home_system_connections = {}
    for system, connected_home_systems in system_hs.items():
        if len(connected_home_systems) >= 2:
            for hs1, hs2 in unique_product(connected_home_systems,
                                           connected_home_systems):
                home_system_connections.setdefault(hs1, set()).add(hs2)
                home_system_connections.setdefault(hs2, set()).add(hs1)

    for system, connected_home_systems in system_hs.items():
        adj_systems = fo.systems_within_jumps_unordered(1, [system])
        for system2 in adj_systems:
            connected_home_systems2 = system_hs.get(system2, set())
            for hs1, hs2 in unique_product(connected_home_systems,
                                           connected_home_systems2):
                home_system_connections.setdefault(hs1, set()).add(hs2)
                home_system_connections.setdefault(hs2, set()).add(hs1)
    return home_system_connections
Esempio n. 8
0
def home_system_team_core(home_systems: List[int],
                          teams: List[Tuple[int, int]]) -> Dict[int, int]:
    """
    Choose core for teams which is a list of pairs team id and count of empires in the team.
    Returns map from team to core home system.
    """
    if not teams:
        return {}
    debug("Teams: %s", teams)
    # sort all home systems by distance
    home_systems_distances = {}
    for hs1, hs2 in unique_product(home_systems, home_systems):
        dist = fo.jump_distance(hs1, hs2)
        home_systems_distances[(hs1, hs2)] = dist
    home_systems_sorted = sorted(home_systems_distances.items(),
                                 key=itemgetter(1),
                                 reverse=True)
    debug("Home systems sorted: %s", home_systems_sorted)

    result = {}
    if not home_systems_sorted:
        pass
    elif len(teams) == 1:
        first_team = teams[0][0]
        first_of_most_distant_systems = home_systems_sorted[0][0][0]
        result[first_team] = first_of_most_distant_systems
    else:
        first_team = teams[0][0]
        first_of_most_distant_systems = home_systems_sorted[0][0][0]
        second_team = teams[1][0]
        second_of_most_distant_systems = home_systems_sorted[0][0][1]
        result[first_team] = first_of_most_distant_systems
        result[second_team] = second_of_most_distant_systems
        if len(teams) > 2:
            warning("Teamed placement poorly implemented for %d teams",
                    len(teams))
    return result
Esempio n. 9
0
def find_systems_with_min_jumps_between(num_systems, systems_pool, min_jumps):
    """
    Find requested number of systems out of a pool that are at least a specified number of jumps apart.
    """
    # make several tries to get the requested number of systems
    attempts = min(100, len(systems_pool))
    while attempts > 0:
        attempts -= 1
        # shuffle our pool of systems so each try the candidates are tried in different order
        # (otherwise each try would yield the same result, which would make trying several times kind of pointless...)
        random.shuffle(systems_pool)
        # try to find systems that meet our condition until we either have the requested number
        # or we have tried all systems in our pool
        accepted = []
        for candidate in systems_pool:
            # check if our candidate is at least min_jumps away from all other systems we already found
            if all(fo.jump_distance(candidate, system) >= min_jumps for system in accepted):
                # if yes, add the candidate to the list of accepted systems
                accepted.append(candidate)
                # if we have the requested number of systems, we can stop and return the systems we found
                if len(accepted) >= num_systems:
                    return accepted
    # all tries failed, return an empty list to indicate failure
    return []