Example #1
0
def score_planet(pw: planet_wars.PlanetWars, p: planet_wars.Planet):
    """
    Function to give a planet a score based on many factors.
    :param pw: `PlanetWars` object
    :param p: `Planet` object
    :return: `float` score of planet
    """

    raw_score = get_raw_score(p)

    structural_score = 1 - (pythag(MY_PLANETS_CENTER,
                                   (p.x(), p.y())) / pw.map_size)

    surrounding_score = 0
    for planet in filter(lambda _p: _p != p, pw.planets()):
        temp = (
            1 -
            (pw.distance(p.planet_id(), planet.planet_id()) / pw.map_size))**5
        surrounding_score += get_raw_score(planet) * temp
    surrounding_score /= pw.total_growth

    latency_score = p.latency / pw.map_size

    center_score = 1 - (pw.distance(p.planet_id(), 0) / pw.map_size)

    score = 0
    score += raw_score
    score += STRUCTURAL_FACTOR * structural_score
    score += SURROUNDING_FACTOR * surrounding_score
    score += LATENCY_FACTOR * latency_score
    score += CENTER_FACTOR * center_score

    return score
Example #2
0
def furthest_meaningful_planet(pw: planet_wars.PlanetWars,
                               planet: planet_wars.Planet, owner: int):
    planets = tuple(filter(lambda p: p.owner() == owner, pw.planets()))
    fleets = tuple(filter(lambda f: f.owner() == owner, pw.fleets()))

    furthest_distance = 0
    for other_planet in planets:
        furthest_distance = max(
            furthest_distance,
            pw.distance(other_planet.planet_id(), planet.planet_id()))
    for fleet in fleets:
        furthest_distance = max(
            furthest_distance,
            fleet.turns_remaining() +
            pw.distance(fleet.destination_planet(), planet.planet_id()))

    return furthest_distance
Example #3
0
def expand(pw: planet_wars.PlanetWars,
           expand_limit: int = 99,
           possible_planets=None,
           reckless: bool = False):
    """
    Expand to neutral planets with all ships. Designed to come after `defend_possible()` because this doesn't account
    for possible attacks from the opponent.
    :param pw: `PlanetWars` object
    :param expand_limit: `int` the maximum number of planets to expand to.
    :param possible_planets: `list` of `Planet` objects, the planets to consider expanding to. None -> all
    :param reckless: `bool` whether to care about the defensibility of the planet
    :return: None
    """

    expand_limit = min(expand_limit, len(pw.neutral_planets()))

    if possible_planets is None:
        possible_planets = filter(lambda p: p not in pw.my_future_neutrals,
                                  pw.neutral_planets())

    possible_planets = filter(lambda p: p not in pw.enemy_future_neutrals,
                              possible_planets)
    sorted_planets = sorted(
        possible_planets,
        key=lambda p:
        (score_planet(pw, p) - get_raw_score(p) + return_ships(pw, p) /
         (pw.map_size / 2)) / (p.num_ships() + 1),
        reverse=True)

    for _ in range(expand_limit):
        for attack_planet in sorted_planets[:expand_limit]:
            if not (attack_planet.latency > 0 and attack_planet.num_ships() < attack_planet.growth_rate()) and \
                    not reckless and not defensible(pw, attack_planet):
                continue
            # if not reckless and not defensible(pw, attack_planet):
            #     continue

            quickest_planet = min(
                pw.my_planets(),
                key=lambda p: turn_to_take(pw, p, attack_planet))

            closest_distance = pw.map_size
            for enemy_planet in pw.enemy_planets():
                closest_distance = min(
                    closest_distance,
                    pw.distance(enemy_planet.planet_id(),
                                attack_planet.planet_id()))
            for enemy_planet in pw.enemy_future_neutrals:
                closest_distance = min(
                    closest_distance,
                    pw.distance(enemy_planet.planet_id(),
                                attack_planet.planet_id()) +
                    pw.enemy_future_neutrals[enemy_planet][0])

            if turn_to_take(pw, quickest_planet,
                            attack_planet) > closest_distance:
                continue

            if quickest_planet.num_ships() > attack_planet.num_ships():
                pw.issue_order(quickest_planet.planet_id(),
                               attack_planet.planet_id(),
                               attack_planet.num_ships() + 1)
                quickest_planet.remove_ships(attack_planet.num_ships() + 1)
                pw.my_future_neutrals[attack_planet] = (pw.distance(
                    quickest_planet.planet_id(), attack_planet.planet_id()), 1)

                for planet in pw.planets():
                    planet.my_maximum_ships[pw.distance(quickest_planet.planet_id(), planet.planet_id()) - 1] -= \
                        attack_planet.num_ships()
                    planet.my_maximum_ships[
                        pw.distance(quickest_planet.planet_id(),
                                    attack_planet.planet_id()) +
                        pw.distance(attack_planet.planet_id(),
                                    planet.planet_id())] += 1
                    for t in range(
                            pw.distance(quickest_planet.planet_id(),
                                        attack_planet.planet_id()) +
                            pw.distance(attack_planet.planet_id(),
                                        planet.planet_id()), 2 * pw.map_size):
                        planet.my_maximum_ships[
                            t] += attack_planet.growth_rate()

                expand_limit -= 1
                sorted_planets.remove(attack_planet)
                break
            else:
                quickest_planet.num_ships(0)
                return
        else:
            break