Exemplo n.º 1
0
def colony_pod_cost_turns():
    empire = fo.getEmpire()
    empire_id = empire.empireID
    loc = INVALID_ID
    pid = INVALID_ID
    parts = [get_ship_part(part) for part in list(empire.availableShipParts)]
    colo_parts = [
        part for part in parts if part.partClass in frozenset({fo.shipPartClass.colony}) and part.capacity > 0
    ]
    if colo_parts:
        colo_part = max(colo_parts, key=lambda x: x.capacity)
        base_cost = colo_part.productionCost(empire_id, pid, loc)
        build_turns = colo_part.productionTime(empire_id, pid, loc)
    else:
        base_cost = 0
        build_turns = 0
        debug("no available colony parts with capacity > 0")
    return (base_cost * (1 + get_number_of_colonies() * AIDependencies.COLONY_POD_UPKEEP), build_turns)
Exemplo n.º 2
0
def outpod_pod_cost():
    return AIDependencies.OUTPOST_POD_COST * (1 + get_number_of_colonies() * AIDependencies.COLONY_POD_UPKEEP)
Exemplo n.º 3
0
def _calculate_invasion_priority():
    """Calculates the demand for troop ships by opponent planets."""

    aistate = get_aistate()
    if not aistate.character.may_invade():
        return 0

    empire = fo.getEmpire()
    enemies_sighted = aistate.misc.get('enemies_sighted', {})
    multiplier = 1
    colony_growth_barrier = aistate.character.max_number_colonies()
    if get_number_of_colonies() > colony_growth_barrier:
        return 0.0

    if len(aistate.colonisablePlanetIDs) > 0:
        best_colony_score = max(
            2,
            next(iter(aistate.colonisablePlanetIDs.items()))[1][0])
    else:
        best_colony_score = 2

    total_val = 0
    troops_needed = 0
    for pid, pscore, trp in AIstate.invasionTargets[:allotted_invasion_targets(
    )]:
        if pscore > best_colony_score:
            multiplier += 1
            total_val += 2 * pscore
        else:
            total_val += pscore
        troops_needed += trp + 4  # ToDo: This seems like it could be improved by some dynamic calculation of buffer

    if total_val == 0:
        return 0

    production_queue = empire.productionQueue
    queued_troop_capacity = 0
    for queue_index in range(0, len(production_queue)):
        element = production_queue[queue_index]
        if element.buildType == EmpireProductionTypes.BT_SHIP:
            if aistate.get_ship_role(element.designID) in [
                    ShipRoleType.MILITARY_INVASION, ShipRoleType.BASE_INVASION
            ]:
                design = fo.getShipDesign(element.designID)
                queued_troop_capacity += element.remaining * element.blocksize * design.troopCapacity
    _, best_design, _ = ProductionAI.get_best_ship_info(
        PriorityType.PRODUCTION_INVASION)
    if best_design:
        troops_per_best_ship = best_design.troopCapacity
    else:
        return 1e-6  # if we can not build troop ships, we don't want to build (non-existing) invasion ships

    # don't count troop bases here as these cannot be redeployed after misplaning
    # troopFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(MissionType.INVASION)\
    #                 + FleetUtilsAI.get_empire_fleet_ids_by_role(MissionType.ORBITAL_INVASION)
    troop_fleet_ids = FleetUtilsAI.get_empire_fleet_ids_by_role(
        MissionType.INVASION)
    total_troop_capacity = sum(
        [FleetUtilsAI.count_troops_in_fleet(fid) for fid in troop_fleet_ids])
    troop_ships_needed = \
        math.ceil((troops_needed - (total_troop_capacity + queued_troop_capacity)) / troops_per_best_ship)

    # invasion_priority = max( 10+ 200*max(0, troop_ships_needed ) , int(0.1* total_val) )
    invasion_priority = multiplier * (30 + 150 * max(0, troop_ships_needed))
    if not ColonisationAI.colony_status.get('colonies_under_attack', []):
        if not ColonisationAI.colony_status.get('colonies_under_threat', []):
            invasion_priority *= 2.0
        else:
            invasion_priority *= 1.5
    if not enemies_sighted:
        invasion_priority *= 1.5

    if invasion_priority < 0:
        return 0

    return invasion_priority * aistate.character.invasion_priority_scaling()
Exemplo n.º 4
0
def _calculate_outpost_priority():
    """Calculates the demand for outpost ships by colonisable planets."""
    global allotted_outpost_targets
    base_outpost_cost = AIDependencies.OUTPOST_POD_COST

    aistate = get_aistate()
    enemies_sighted = aistate.misc.get('enemies_sighted', {})
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    total_pp = fo.getEmpire().productionPoints
    colony_growth_barrier = aistate.character.max_number_colonies()
    if get_number_of_colonies() > colony_growth_barrier:
        return 0.0
    mil_prio = aistate.get_priority(PriorityType.PRODUCTION_MILITARY)

    not_sparse, enemy_unseen = 0, 0
    is_sparse, enemy_seen = 1, 1
    allotted_portion = {
        (not_sparse, enemy_unseen): (0.6, 0.8),
        (not_sparse, enemy_seen): (0.3, 0.4),
        (is_sparse, enemy_unseen): (0.8, 0.9),
        (is_sparse, enemy_seen): (0.3, 0.4),
    }[(galaxy_is_sparse, any(enemies_sighted))]
    allotted_portion = aistate.character.preferred_outpost_portion(
        allotted_portion)
    if mil_prio < 100:
        allotted_portion *= 2
    elif mil_prio < 200:
        allotted_portion *= 1.5
    allotted_outpost_targets = 1 + int(
        total_pp * 3 * allotted_portion / base_outpost_cost)

    num_outpost_targets = len([
        pid
        for (pid, (score, specName)) in aistate.colonisableOutpostIDs.items()
        if score > max(1.0 * base_outpost_cost /
                       3.0, ColonisationAI.MINIMUM_COLONY_SCORE)
    ][:allotted_outpost_targets])
    if num_outpost_targets == 0 or not tech_is_complete(
            AIDependencies.OUTPOSTING_TECH):
        return 0

    outpost_ship_ids = FleetUtilsAI.get_empire_fleet_ids_by_role(
        MissionType.OUTPOST)
    num_outpost_ships = len(
        FleetUtilsAI.extract_fleet_ids_without_mission_types(outpost_ship_ids))
    outpost_priority = (
        50.0 * (num_outpost_targets - num_outpost_ships)) / num_outpost_targets

    # discourage early outposting for SP_SLY, due to supply and stealth considerations they are best off
    # using colony ships until they have other colonizers (and more established military)
    if list(ColonisationAI.empire_colonizers) == ["SP_SLY"]:
        outpost_priority /= 3.0

    # print
    # print "Number of Outpost Ships : " + str(num_outpost_ships)
    # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids)
    debug("Priority for outpost ships: %s" % outpost_priority)

    if outpost_priority < 1:
        return 0
    return outpost_priority
Exemplo n.º 5
0
def _calculate_colonisation_priority():
    """Calculates the demand for colony ships by colonisable planets."""
    global allottedColonyTargets
    aistate = get_aistate()
    enemies_sighted = aistate.misc.get('enemies_sighted', {})
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    total_pp = fo.getEmpire().productionPoints
    num_colonies = get_number_of_colonies()
    colony_growth_barrier = aistate.character.max_number_colonies()
    if num_colonies > colony_growth_barrier:
        return 0.0
    colony_cost, turns_to_build = (ColonisationAI.colony_pod_cost_turns())

    mil_prio = aistate.get_priority(PriorityType.PRODUCTION_MILITARY)
    allotted_portion = ([[[0.6, 0.8], [0.3, 0.4]],
                         [[0.8, 0.9],
                          [0.4, 0.6]]][galaxy_is_sparse][any(enemies_sighted)])
    allotted_portion = aistate.character.preferred_colonization_portion(
        allotted_portion)
    # if ( get_aistate().get_priority(AIPriorityType.PRIORITY_PRODUCTION_COLONISATION)
    # > 2 * get_aistate().get_priority(AIPriorityType.PRIORITY_PRODUCTION_MILITARY)):
    # allotted_portion *= 1.5
    if mil_prio < 100:
        allotted_portion *= 2
    elif mil_prio < 200:
        allotted_portion *= 1.5
    elif fo.currentTurn() > 100:
        allotted_portion *= 0.75**(num_colonies / 10.0)
    # allottedColonyTargets = 1+ int(fo.currentTurn()/50)
    allottedColonyTargets = 1 + int(
        total_pp * turns_to_build * allotted_portion / colony_cost)
    outpost_prio = aistate.get_priority(PriorityType.PRODUCTION_OUTPOST)

    # if have no SP_SLY, and have any outposts to build, don't build colony ships TODO: make more complex assessment
    colonizers = list(ColonisationAI.empire_colonizers)
    if "SP_SLY" not in colonizers and outpost_prio > 0:
        return 0.0
    min_score = ColonisationAI.MINIMUM_COLONY_SCORE
    minimal_top = min_score + 2  # one more than the conditional floor set by ColonisationAI.revise_threat_factor()
    minimal_opportunities = [
        species_name
        for (_, (score, species_name)) in aistate.colonisablePlanetIDs.items()
        if min_score < score <= minimal_top
    ]
    decent_opportunities = [
        species_name
        for (_, (score, species_name)) in aistate.colonisablePlanetIDs.items()
        if score > minimal_top
    ]
    minimal_planet_factor = 0.2  # count them for something, but not much
    num_colonisable_planet_ids = len(
        decent_opportunities
    ) + minimal_planet_factor * len(minimal_opportunities)
    if num_colonisable_planet_ids == 0:
        return 1

    colony_ship_ids = FleetUtilsAI.get_empire_fleet_ids_by_role(
        MissionType.COLONISATION)
    num_colony_ships = len(
        FleetUtilsAI.extract_fleet_ids_without_mission_types(colony_ship_ids))
    colonisation_priority = 60 * (1.0 + num_colonisable_planet_ids -
                                  num_colony_ships) / (
                                      num_colonisable_planet_ids + 1)

    if colonizers == ["SP_SLY"]:
        colonisation_priority *= 2
    elif "SP_SLY" in colonizers:
        colony_opportunities = minimal_opportunities + decent_opportunities
        colonisation_priority *= (1.0 + colony_opportunities.count("SP_SLY")
                                  ) / len(colony_opportunities)

    # print
    # print "Number of Colony Ships : " + str(num_colony_ships)
    # print "Number of Colonisable planets : " + str(num_colonisable_planet_ids)
    # print "Priority for colony ships : " + str(colonisation_priority)

    if colonisation_priority < 1:
        return 0
    return colonisation_priority
Exemplo n.º 6
0
def _calculate_research_priority():
    """Calculates the AI empire's demand for research."""
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    current_turn = fo.currentTurn()
    aistate = get_aistate()
    enemies_sighted = aistate.misc.get('enemies_sighted', {})
    recent_enemies = [x for x in enemies_sighted if x > current_turn - 8]

    industry_priority = aistate.get_priority(PriorityType.RESOURCE_PRODUCTION)

    got_algo = tech_is_complete(AIDependencies.LRN_ALGO_ELEGANCE)
    got_quant = tech_is_complete(AIDependencies.LRN_QUANT_NET)
    research_queue_list = ResearchAI.get_research_queue_techs()
    orb_gen_tech = AIDependencies.PRO_ORBITAL_GEN
    got_orb_gen = tech_is_complete(orb_gen_tech)
    mgrav_prod_tech = AIDependencies.PRO_MICROGRAV_MAN
    got_mgrav_prod = tech_is_complete(mgrav_prod_tech)
    # got_solar_gen = tech_is_complete(AIDependencies.PRO_SOL_ORB_GEN)

    milestone_techs = [
        "PRO_ADAPTIVE_AUTOMATION", "LRN_DISTRIB_THOUGHT", "LRN_QUANT_NET",
        "SHP_WEAPON_2_4", "SHP_WEAPON_3_2", "SHP_WEAPON_4_2"
    ]
    milestones_done = [
        mstone for mstone in milestone_techs if tech_is_complete(mstone)
    ]
    debug("Research Milestones accomplished at turn %d: %s" %
          (current_turn, milestones_done))

    total_pp = empire.productionPoints
    total_rp = empire.resourceProduction(fo.resourceType.research)
    industry_surge = (
        aistate.character.may_surge_industry(total_pp, total_rp)
        and (((orb_gen_tech in research_queue_list[:2] or got_orb_gen)
              and have_gas_giant()) or
             ((mgrav_prod_tech in research_queue_list[:2] or got_mgrav_prod)
              and have_asteroids())) and (get_number_of_colonies() < 12))
    # get current industry production & Target
    owned_planet_ids = PlanetUtilsAI.get_owned_planets_by_empire(
        universe.planetIDs)
    planets = (universe.getPlanet(x) for x in owned_planet_ids)
    target_rp = sum(
        map(lambda _x: _x.currentMeterValue(fo.meterType.targetResearch),
            planets))
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    enemies_sighted = aistate.misc.get('enemies_sighted', {})

    style_index = aistate.character.preferred_research_cutoff([0, 1])
    if aistate.character.may_maximize_research():
        style_index += 1

    cutoff_sets = [[25, 45, 70, 110], [30, 45, 70, 150], [25, 40, 80, 160]]
    cutoffs = cutoff_sets[style_index]
    settings = [[1.3, .7, .5, .4, .35], [1.4, 0.8, 0.6, 0.5, 0.35],
                [1.4, 0.8, 0.6, 0.5, 0.4]][style_index]

    if (current_turn < cutoffs[0]) or (not got_algo) or (
        (style_index == 0) and not got_orb_gen and
        (current_turn < cutoffs[1])):
        research_priority = settings[
            0] * industry_priority  # high research at beginning of game to get easy gro tech and to get research booster Algotrithmic Elegance
    elif (not got_orb_gen) or (current_turn < cutoffs[1]):
        research_priority = settings[1] * industry_priority  # med-high research
    elif current_turn < cutoffs[2]:
        research_priority = settings[2] * industry_priority  # med-high industry
    elif current_turn < cutoffs[3]:
        research_priority = settings[3] * industry_priority  # med-high industry
    else:
        research_queue = list(empire.researchQueue)
        research_priority = settings[
            4] * industry_priority  # high industry , low research
        if len(research_queue) == 0:
            research_priority = 0  # done with research
        elif len(research_queue) < 5 and research_queue[-1].allocation > 0:
            research_priority = len(
                research_queue
            ) * 0.01 * industry_priority  # barely not done with research
        elif len(research_queue) < 10 and research_queue[-1].allocation > 0:
            research_priority = (
                4 + 2 * len(research_queue)
            ) * 0.01 * industry_priority  # almost done with research
        elif len(research_queue) < 20 and research_queue[int(
                len(research_queue) // 2)].allocation > 0:
            research_priority *= 0.7  # closing in on end of research
    if industry_surge:
        if galaxy_is_sparse and not any(enemies_sighted):
            research_priority *= 0.5
        else:
            research_priority *= 0.8

    if ((tech_is_complete("SHP_WEAPON_2_4")
         or tech_is_complete("SHP_WEAPON_4_1"))
            and tech_is_complete(AIDependencies.PRO_AUTO_1)):
        # industry_factor = [ [0.25, 0.2], [0.3, 0.25], [0.3, 0.25] ][style_index ]
        # researchPriority = min(researchPriority, industry_factor[got_solar_gen]*industryPriority)
        research_priority *= 0.9
    if got_quant:
        research_priority = min(research_priority + 0.1 * industry_priority,
                                research_priority * 1.3)
    research_priority = int(research_priority)
    debug("Research Production (current/target) : ( %.1f / %.1f )" %
          (total_rp, target_rp))
    debug(
        "Priority for Research: %d (new target ~ %d RP)" %
        (research_priority, total_pp * research_priority / industry_priority))

    if len(enemies_sighted) < (
            2 + current_turn / 20.0):  # TODO: adjust for colonisation priority
        research_priority *= 1.2
    if (current_turn > 20) and (len(recent_enemies) > 3):
        research_priority *= 0.8
    return research_priority