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)
def outpod_pod_cost(): return AIDependencies.OUTPOST_POD_COST * (1 + get_number_of_colonies() * AIDependencies.COLONY_POD_UPKEEP)
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()
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
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
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