def _calculate_colonisation_priority(): """Calculates the demand for colony ships by colonisable planets.""" global allottedColonyTargets enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() colony_cost = AIDependencies.COLONY_POD_COST * ( 1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turns_to_build = 8 # TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.character.preferred_colonization_portion( allotted_portion) # if ( foAI.foAIstate.get_priority(AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.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 = foAI.foAIstate.get_priority(PriorityType.PRODUCTION_OUTPOST) # if have any outposts to build, don't build colony ships TODO: make more complex assessment if outpost_prio > 0 or num_colonies > colony_growth_barrier: return 0.0 if num_colonies > colony_growth_barrier: return 0.0 num_colonisable_planet_ids = len([ pid for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items() if score > 60 ][:allottedColonyTargets + 2]) 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) # 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 calculateColonisationPriority(): """calculates the demand for colony ships by colonisable planets""" global allottedColonyTargets, colony_growth_barrier enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) # significant growth barrier for low aggression, negligible for high aggression colony_growth_barrier = 2 + ( (0.5 + foAI.foAIstate.aggression)**2) * fo.currentTurn() / 50.0 colonyCost = AIDependencies.COLONY_POD_COST * ( 1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turnsToBuild = 8 # TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.get_priority( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) allottedPortion = ([[[0.6, 0.8], [0.3, 0.4]], [[0.8, 0.9], [ 0.3, 0.4 ]]][galaxy_is_sparse][any(enemies_sighted)][fo.empireID() % 2]) #if ( foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)): # allottedPortion *= 1.5 if mil_prio < 100: allottedPortion *= 2 elif mil_prio < 200: allottedPortion *= 1.5 elif fo.currentTurn() > 100: allottedPortion *= 0.75**(num_colonies / 10.0) #allottedColonyTargets = 1+ int(fo.currentTurn()/50) allottedColonyTargets = 1 + int( total_pp * turnsToBuild * allottedPortion / colonyCost) outpost_prio = foAI.foAIstate.get_priority( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_OUTPOST) # if have any outposts to build, don't build colony ships TODO: make more complex assessment if outpost_prio > 0 or num_colonies > colony_growth_barrier: return 0.0 if num_colonies > colony_growth_barrier: return 0.0 numColonisablePlanetIDs = len([ pid for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items() if score > 60 ][:allottedColonyTargets + 2]) if numColonisablePlanetIDs == 0: return 1 colonyshipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role( EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION) numColonyships = len( FleetUtilsAI.extract_fleet_ids_without_mission_types(colonyshipIDs)) colonisationPriority = 60 * (1 + numColonisablePlanetIDs - numColonyships ) / (numColonisablePlanetIDs + 1) # print # print "Number of Colony Ships : " + str(numColonyships) # print "Number of Colonisable planets : " + str(numColonisablePlanetIDs) # print "Priority for colony ships : " + str(colonisationPriority) if colonisationPriority < 1: return 0 return colonisationPriority
def _calculate_outpost_priority(): """Calculates the demand for outpost ships by colonisable planets.""" global allotted_outpost_targets base_outpost_cost = AIDependencies.OUTPOST_POD_COST enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() if num_colonies > colony_growth_barrier: return 0.0 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.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 foAI.foAIstate.colonisableOutpostIDs.items() if score > 1.0 * base_outpost_cost / 3.0 ][: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 # print # print "Number of Outpost Ships : " + str(num_outpost_ships) # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids) print "Priority for outpost ships: " + str(outpost_priority) if outpost_priority < 1: return 0 return outpost_priority
def calculateOutpostPriority(): """calculates the demand for outpost ships by colonisable planets""" global allotted_outpost_targets base_outpost_cost = AIDependencies.OUTPOST_POD_COST enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) # significant growth barrier for low aggression, negligible for high aggression if num_colonies > colony_growth_barrier: return 0.0 mil_prio = foAI.foAIstate.get_priority( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) NOT_SPARCE, ENEMY_UNSEEN = 0, 0 IS_SPARCE, ENEMY_SEEN = 1, 1 allotted_portion = { (NOT_SPARCE, ENEMY_UNSEEN): (0.6, 0.8), (NOT_SPARCE, ENEMY_SEEN): (0.3, 0.4), (IS_SPARCE, ENEMY_UNSEEN): (0.8, 0.9), (IS_SPARCE, ENEMY_SEEN): (0.3, 0.4), }[(galaxy_is_sparse, any(enemies_sighted))][fo.empireID() % 2] 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 foAI.foAIstate.colonisableOutpostIDs.items() if score > 1.0 * base_outpost_cost / 3.0 ][:allotted_outpost_targets]) if num_outpost_targets == 0 or not tech_is_complete( AIDependencies.OUTPOSTING_TECH): return 0 outpostShipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role( EnumsAI.AIFleetMissionType.FLEET_MISSION_OUTPOST) num_outpost_ships = len( FleetUtilsAI.extract_fleet_ids_without_mission_types(outpostShipIDs)) outpost_priority = 50 * (num_outpost_targets - num_outpost_ships) / num_outpost_targets # print # print "Number of Outpost Ships : " + str(num_outpost_ships) # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids) print "Priority for outpost ships : " + str(outpost_priority) if outpost_priority < 1: return 0 return outpost_priority
def calculateColonisationPriority(): """calculates the demand for colony ships by colonisable planets""" global allottedColonyTargets, colony_growth_barrier enemies_sighted = foAI.foAIstate.misc.get("enemies_sighted", {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) # significant growth barrier for low aggression, negligible for high aggression colony_growth_barrier = 2 + ((0.5 + foAI.foAIstate.aggression) ** 2) * fo.currentTurn() / 50.0 colonyCost = AIDependencies.COLONY_POD_COST * (1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turnsToBuild = 8 # TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) allottedPortion = [[[0.6, 0.8], [0.3, 0.4]], [[0.8, 0.9], [0.3, 0.4]]][galaxy_is_sparse][any(enemies_sighted)][ fo.empireID() % 2 ] # if ( foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)): # allottedPortion *= 1.5 if mil_prio < 100: allottedPortion *= 2 elif mil_prio < 200: allottedPortion *= 1.5 elif fo.currentTurn() > 100: allottedPortion *= 0.75 ** (num_colonies / 10.0) # allottedColonyTargets = 1+ int(fo.currentTurn()/50) allottedColonyTargets = 1 + int(total_pp * turnsToBuild * allottedPortion / colonyCost) outpost_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_OUTPOST) # if have any outposts to build, don't build colony ships TODO: make more complex assessment if outpost_prio > 0 or num_colonies > colony_growth_barrier: return 0.0 if num_colonies > colony_growth_barrier: return 0.0 numColonisablePlanetIDs = len( [pid for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items() if score > 60][ : allottedColonyTargets + 2 ] ) if numColonisablePlanetIDs == 0: return 1 colonyshipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION) numColonyships = len(FleetUtilsAI.extract_fleet_ids_without_mission_types(colonyshipIDs)) colonisationPriority = 60 * (1 + numColonisablePlanetIDs - numColonyships) / (numColonisablePlanetIDs + 1) # print # print "Number of Colony Ships : " + str(numColonyships) # print "Number of Colonisable planets : " + str(numColonisablePlanetIDs) # print "Priority for colony ships : " + str(colonisationPriority) if colonisationPriority < 1: return 0 return colonisationPriority
def calculateOutpostPriority(): """calculates the demand for outpost ships by colonisable planets""" global allotted_outpost_targets base_outpost_cost = AIDependencies.OUTPOST_POD_COST enemies_sighted = foAI.foAIstate.misc.get("enemies_sighted", {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) # significant growth barrier for low aggression, negligible for high aggression if num_colonies > colony_growth_barrier: return 0.0 mil_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) NOT_SPARCE, ENEMY_UNSEEN = 0, 0 IS_SPARCE, ENEMY_SEEN = 1, 1 allotted_portion = { (NOT_SPARCE, ENEMY_UNSEEN): (0.6, 0.8), (NOT_SPARCE, ENEMY_SEEN): (0.3, 0.4), (IS_SPARCE, ENEMY_UNSEEN): (0.8, 0.9), (IS_SPARCE, ENEMY_SEEN): (0.3, 0.4), }[(galaxy_is_sparse, any(enemies_sighted))][fo.empireID() % 2] 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 foAI.foAIstate.colonisableOutpostIDs.items() if score > 1.0 * base_outpost_cost / 3.0 ][:allotted_outpost_targets] ) if num_outpost_targets == 0 or not tech_is_complete(AIDependencies.OUTPOSTING_TECH): return 0 outpostShipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_OUTPOST) num_outpost_ships = len(FleetUtilsAI.extract_fleet_ids_without_mission_types(outpostShipIDs)) outpost_priority = 50 * (num_outpost_targets - num_outpost_ships) / num_outpost_targets # print # print "Number of Outpost Ships : " + str(num_outpost_ships) # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids) print "Priority for outpost ships : " + str(outpost_priority) if outpost_priority < 1: return 0 return outpost_priority
def _calculate_outpost_priority(): """Calculates the demand for outpost ships by colonisable planets.""" global allotted_outpost_targets base_outpost_cost = AIDependencies.OUTPOST_POD_COST enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() if state.get_number_of_colonies() > colony_growth_barrier: return 0.0 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.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 foAI.foAIstate.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) print "Priority for outpost ships: " + str(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 enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() colony_cost = AIDependencies.COLONY_POD_COST * (1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turns_to_build = 8 # TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.character.preferred_colonization_portion(allotted_portion) # if ( foAI.foAIstate.get_priority(AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.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 = foAI.foAIstate.get_priority(PriorityType.PRODUCTION_OUTPOST) # if have any outposts to build, don't build colony ships TODO: make more complex assessment if outpost_prio > 0 or num_colonies > colony_growth_barrier: return 0.0 if num_colonies > colony_growth_barrier: return 0.0 num_colonisable_planet_ids = len([pid for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items() if score > 60][:allottedColonyTargets + 2]) 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 + num_colonisable_planet_ids - num_colony_ships) / (num_colonisable_planet_ids + 1) # 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_outpost_priority(): """Calculates the demand for outpost ships by colonisable planets.""" global allotted_outpost_targets base_outpost_cost = AIDependencies.OUTPOST_POD_COST enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = len(list(AIstate.popCtrIDs)) colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() if num_colonies > colony_growth_barrier: return 0.0 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.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 foAI.foAIstate.colonisableOutpostIDs.items() if score > 1.0 * base_outpost_cost / 3.0][: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 * (num_outpost_targets - num_outpost_ships) / num_outpost_targets # print # print "Number of Outpost Ships : " + str(num_outpost_ships) # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids) print "Priority for outpost ships: " + str(outpost_priority) if outpost_priority < 1: return 0 return outpost_priority
def calculateColonisationPriority(): """calculates the demand for colony ships by colonisable planets""" global allottedColonyTargets, colonyGrowthBarrier enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted',{}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() totalPP=fo.getEmpire().productionPoints num_colonies = len( list(AIstate.popCtrIDs) ) colonyGrowthBarrier = 2 + ((0.5+foAI.foAIstate.aggression)**2)*fo.currentTurn()/50.0 #significant for low aggression, negligible for high aggression if num_colonies > colonyGrowthBarrier: return 0.0 colonyCost=120*(1+ 0.06*num_colonies) turnsToBuild=8#TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) allottedPortion = [[[0.6, 0.8],[0.3, 0.4]],[[0.8, 0.9],[0.3, 0.4]]][galaxy_is_sparse][any(enemies_sighted)][fo.empireID() % 2] # #if ( foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)): # allottedPortion *= 1.5 if mil_prio < 100: allottedPortion *= 2 elif mil_prio < 200: allottedPortion *= 1.5 elif fo.currentTurn() > 100: allottedPortion *= 0.75**(num_colonies/10.0) #allottedColonyTargets = 1+ int(fo.currentTurn()/50) allottedColonyTargets = 1 + int( totalPP*turnsToBuild*allottedPortion/colonyCost) numColonisablePlanetIDs = len( [ pid for (pid, (score, specName) ) in foAI.foAIstate.colonisablePlanetIDs if score > 60 ][:allottedColonyTargets+2] ) if numColonisablePlanetIDs == 0: return 1 colonyshipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION) numColonyships = len(FleetUtilsAI.extract_fleet_ids_without_mission_types(colonyshipIDs)) colonisationPriority = 60 * (1+numColonisablePlanetIDs - numColonyships) / (numColonisablePlanetIDs+1) # print # print "Number of Colony Ships : " + str(numColonyships) # print "Number of Colonisable planets : " + str(numColonisablePlanetIDs) # print "Priority for colony ships : " + str(colonisationPriority) if colonisationPriority < 1: return 1 return colonisationPriority
def _calculate_research_priority(): """Calculates the AI empire's demand for research.""" universe = fo.getUniverse() empire = fo.getEmpire() empire_id = empire.empireID current_turn = fo.currentTurn() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) recent_enemies = [x for x in enemies_sighted if x > current_turn - 8] industry_priority = foAI.foAIstate.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_SENTIENT_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)] print "Research Milestones accomplished at turn %d: %s" % (current_turn, milestones_done) total_pp = empire.productionPoints total_rp = empire.resourceProduction(fo.resourceType.research) industry_surge = (foAI.foAIstate.character.may_surge_industry(total_pp, total_rp) and (((orb_gen_tech in research_queue_list[:2] or got_orb_gen) and state.have_gas_giant) or ((mgrav_prod_tech in research_queue_list[:2] or got_mgrav_prod) and state.have_asteroids)) and (not (len(AIstate.popCtrIDs) >= 12))) # get current industry production & Target owned_planet_ids = PlanetUtilsAI.get_owned_planets_by_empire(universe.planetIDs) planets = map(universe.getPlanet, owned_planet_ids) target_rp = sum(map(lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets)) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) style_index = foAI.foAIstate.character.preferred_research_cutoff([0, 1]) if foAI.foAIstate.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.PROD_AUTO_NAME)): # 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) print "Research Production (current/target) : ( %.1f / %.1f )" % (total_rp, target_rp) print "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
def generate_research_orders(): """generate research orders""" report_adjustments = False empire = fo.getEmpire() empire_id = empire.empireID enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() print "Research Queue Management:" resource_production = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n" % resource_production print "Techs researched and available for use:" completed_techs = sorted(list(get_completed_techs())) tlist = completed_techs+3*[" "] tlines = zip(tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s" % tline print # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() inProgressTechs.clear() tech_turns_left = {} if research_queue_list: print "Techs currently at head of Research Queue:" for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft if element.allocation > 0.0: inProgressTechs[element.tech] = True this_tech = fo.getTech(element.tech) if not this_tech: print "Error: can't retrieve tech ", element.tech continue missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: print " %25s allocated %6.2f RP -- unlockable items: %s " % (element.tech, element.allocation, unlocked_items) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s " % (element.tech, element.allocation, missing_prereqs, unlocked_items) print # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() == 1) or ((fo.currentTurn() < 5) and (len(research_queue_list) == 0)): research_index = get_research_index() new_tech = TechsListsAI.sparse_galaxy_techs(research_index) if galaxy_is_sparse else TechsListsAI.primary_meta_techs(research_index) print "Empire %s (%d) is selecting research index %d" % (empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs+research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: print "Error: desired tech '%s' appears to not exist" % tech continue missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs+[tech]) cum_cost = 0 print " Enqueued Tech: %20s \t\t %8s \t %s" % ("Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % (name, this_cost, cum_cost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc() if foAI.foAIstate.aggression <= fo.aggression.cautious: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if def_tech not in research_queue_list[:5] and not tech_is_complete(def_tech): res = fo.issueEnqueueTechOrder(def_tech, min(3, len(research_queue_list))) print "Empire is very defensive, so attempted to fast-track %s, got result %d" % (def_tech, res) if False and foAI.foAIstate.aggression >= fo.aggression.aggressive: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list: insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list)-10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list: insert_idx = min(insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete(cc_tech): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) msg = "Empire is very aggressive, so attempted to fast-track %s, got result %d" % (cc_tech, res) if report_adjustments: chat_human(msg) else: print msg print"" generate_default_research_order() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" # coveredTechs = new_tech+completed_techs for tname in [tn for tn in alltechs if tn not in tech_base]: print tname elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(foAI.foAIstate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = foAI.foAIstate.colonisablePlanetIDs.items()[0][1] if len(foAI.foAIstate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = foAI.foAIstate.colonisableOutpostIDs.items()[0][1] need_improved_scouting = (best_colony_site_score < 150 or best_outpost_site_score < 200) if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]) and ( tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1+num_techs_accelerated]) and ( tech_is_complete("CON_METRO_INFRA")): for supply_tech in [_s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech)]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % (supply_tech, res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_GAL_INFRA"): num_techs_accelerated += 1 if ("CON_GAL_INFRA" not in research_queue_list[:1+num_techs_accelerated]) and ( tech_is_complete("PRO_SINGULAR_GEN")): res = fo.issueEnqueueTechOrder("CON_GAL_INFRA", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_GAL_INFRA", res) if report_adjustments: chat_human(msg) else: print msg else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete("SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2+num_techs_accelerated] and tech_is_complete("PRO_FUSION_GEN"): if "CON_ORBITAL_CON" not in research_queue_list[:1+num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (ColonisationAI.gotRuins and not tech_is_complete("LRN_XENOARCH") and foAI.foAIstate.aggression >= fo.aggression.typical): if "LRN_ARTIF_MINDS" in research_queue_list: insert_idx = 7 + research_queue_list.index("LRN_ARTIF_MINDS") elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in ["LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE"]: if not tech_is_complete(xenoTech) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 msg = "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d" % (xenoTech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_SENTIENT_AUTOMATION", "PRO_SENTIENT_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_SENTIENT_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_SENTIENT_AUTOMATION"]), ("PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", ["PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I"]), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [0, 1, 2]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: print "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s" % (move_tech, target_slot, target_index, num_techs_accelerated) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: res = fo.issueEnqueueTechOrder(move_tech, target_index) msg = "Research: To prioritize %s, have advanced %s to slot %d" % (tech, move_tech, target_index) if report_adjustments: chat_human(msg) else: print msg target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if ColonisationAI.got_ast: insert_idx = num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index("GRO_SYMBIOTIC_BIO") ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % (ast_tech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = (1 + insert_idx) if "LRN_FORCE_FIELD" not in research_queue_list else max(1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1) for ast_tech in ["SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS"]: if not tech_is_complete(ast_tech) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % (ast_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() if ColonisationAI.got_gg and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = 0 if "PRO_FUSION_GEN" not in research_queue_list else (1 + research_queue_list.index("PRO_FUSION_GEN")) forcefields_idx = 0 if "LRN_FORCE_FIELD" not in research_queue_list else (1 + research_queue_list.index("LRN_FORCE_FIELD")) insert_idx = max(fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx+1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 msg = "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d" % ("PRO_ORBITAL_GEN", res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and (not got_xeno_gen) and foAI.foAIstate.aggression >= fo.aggression.cautious: most_adequate = 0 for specName in ColonisationAI.empire_colonizers: environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max(most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if xg_tech not in research_queue_list[:1+num_techs_accelerated] and not tech_is_complete(xg_tech): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 msg = "Empire has poor colonizers, so attempted to fast-track %s, got result %d" % (xg_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in ColonisationAI.empire_species: this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break if (foAI.foAIstate.aggression > fo.aggression.cautious) and (empire.population() > ([300, 100][got_telepathy])): insert_idx = num_techs_accelerated for dt_ech in ["LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT"]: if dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" msg = fmt_str % (dt_ech, res, resource_production, empire.population(), fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if (foAI.foAIstate.aggression > fo.aggression.cautious) and (ColonisationAI.empire_status.get('researchers', 0) >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d" % (qnTech, res, fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and foAI.foAIstate.aggression > fo.aggression.cautious and not tech_is_complete(AIDependencies.PRO_SINGULAR_GEN) and tech_is_complete(AIDependencies.PRO_SOL_ORB_GEN)): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(AIDependencies.PRO_SINGULAR_GEN) sing_tech_list = [pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req)] sing_tech_list += [AIDependencies.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated+1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 msg = "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d" % (singTech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list] if len(missing_prereqs) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx-18))
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 = state.get_number_of_colonies() colony_growth_barrier = aistate.character.max_number_colonies() if num_colonies > colony_growth_barrier: return 0.0 colony_cost = AIDependencies.COLONY_POD_COST * ( 1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turns_to_build = 8 # TODO: check for susp anim pods, build time 10 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 generate_research_orders(): """generate research orders""" report_adjustments = False empire = fo.getEmpire() empire_id = empire.empireID enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() print "Research Queue Management:" resource_production = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n" % resource_production print "Techs researched and available for use:" completed_techs = sorted(list(get_completed_techs())) tlist = completed_techs + 3 * [" "] tlines = zip(tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s" % tline print # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() inProgressTechs.clear() tech_turns_left = {} if research_queue_list: print "Techs currently at head of Research Queue:" for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft if element.allocation > 0.0: inProgressTechs[element.tech] = True this_tech = fo.getTech(element.tech) if not this_tech: print "Error: can't retrieve tech ", element.tech continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs ] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: print " %25s allocated %6.2f RP -- unlockable items: %s " % ( element.tech, element.allocation, unlocked_items) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s " % ( element.tech, element.allocation, missing_prereqs, unlocked_items) print # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() == 1) or ((fo.currentTurn() < 5) and (len(research_queue_list) == 0)): research_index = get_research_index() new_tech = TechsListsAI.sparse_galaxy_techs( research_index ) if galaxy_is_sparse else TechsListsAI.primary_meta_techs( research_index) print "Empire %s (%d) is selecting research index %d" % ( empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs + research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: print "Error: desired tech '%s' appears to not exist" % tech continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base ] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs + [tech]) cum_cost = 0 print " Enqueued Tech: %20s \t\t %8s \t %s" % ("Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % ( name, this_cost, cum_cost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc( ) if foAI.foAIstate.aggression <= fo.aggression.cautious: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if def_tech not in research_queue_list[: 5] and not tech_is_complete( def_tech): res = fo.issueEnqueueTechOrder( def_tech, min(3, len(research_queue_list))) print "Empire is very defensive, so attempted to fast-track %s, got result %d" % ( def_tech, res) if False and foAI.foAIstate.aggression >= fo.aggression.aggressive: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list: insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list) - 10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list: insert_idx = min( insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete( cc_tech): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) msg = "Empire is very aggressive, so attempted to fast-track %s, got result %d" % ( cc_tech, res) if report_adjustments: chat_human(msg) else: print msg print "" generate_default_research_order() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" # coveredTechs = new_tech+completed_techs for tname in [tn for tn in alltechs if tn not in tech_base]: print tname elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(foAI.foAIstate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = foAI.foAIstate.colonisablePlanetIDs.items( )[0][1] if len(foAI.foAIstate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = foAI.foAIstate.colonisableOutpostIDs.items( )[0][1] need_improved_scouting = (best_colony_site_score < 150 or best_outpost_site_score < 200) if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("CON_METRO_INFRA")): for supply_tech in [ _s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech) ]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( supply_tech, res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_GAL_INFRA"): num_techs_accelerated += 1 if ("CON_GAL_INFRA" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_SINGULAR_GEN")): res = fo.issueEnqueueTechOrder("CON_GAL_INFRA", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_GAL_INFRA", res) if report_adjustments: chat_human(msg) else: print msg else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete( "SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2 + num_techs_accelerated] and tech_is_complete( "PRO_FUSION_GEN" ): if "CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (ColonisationAI.gotRuins and not tech_is_complete("LRN_XENOARCH") and foAI.foAIstate.aggression >= fo.aggression.typical): if "LRN_ARTIF_MINDS" in research_queue_list: insert_idx = 7 + research_queue_list.index("LRN_ARTIF_MINDS") elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if not tech_is_complete( xenoTech ) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 msg = "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d" % ( xenoTech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [ ("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_SENTIENT_AUTOMATION", "PRO_SENTIENT_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_SENTIENT_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_SENTIENT_AUTOMATION"]), ("PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", ["PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I"]), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [ 0, 1, 2 ]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: print "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s" % ( move_tech, target_slot, target_index, num_techs_accelerated) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: res = fo.issueEnqueueTechOrder(move_tech, target_index) msg = "Research: To prioritize %s, have advanced %s to slot %d" % ( tech, move_tech, target_index) if report_adjustments: chat_human(msg) else: print msg target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if ColonisationAI.got_ast: insert_idx = num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index( "GRO_SYMBIOTIC_BIO") ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % ( ast_tech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = ( 1 + insert_idx ) if "LRN_FORCE_FIELD" not in research_queue_list else max( 1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1) for ast_tech in [ "SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS" ]: if not tech_is_complete( ast_tech ) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % ( ast_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() if ColonisationAI.got_gg and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = 0 if "PRO_FUSION_GEN" not in research_queue_list else ( 1 + research_queue_list.index("PRO_FUSION_GEN")) forcefields_idx = 0 if "LRN_FORCE_FIELD" not in research_queue_list else ( 1 + research_queue_list.index("LRN_FORCE_FIELD")) insert_idx = max( fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 msg = "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d" % ( "PRO_ORBITAL_GEN", res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and ( not got_xeno_gen ) and foAI.foAIstate.aggression >= fo.aggression.cautious: most_adequate = 0 for specName in ColonisationAI.empire_colonizers: environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [ fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids ]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max( most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if xg_tech not in research_queue_list[:1 + num_techs_accelerated] and not tech_is_complete( xg_tech): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 msg = "Empire has poor colonizers, so attempted to fast-track %s, got result %d" % ( xg_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in ColonisationAI.empire_species: this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break if (foAI.foAIstate.aggression > fo.aggression.cautious) and (empire.population() > ([300, 100][got_telepathy])): insert_idx = num_techs_accelerated for dt_ech in [ "LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT" ]: if dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( dt_ech): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" msg = fmt_str % (dt_ech, res, resource_production, empire.population(), fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if (foAI.foAIstate.aggression > fo.aggression.cautious) and ( ColonisationAI.empire_status.get('researchers', 0) >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d" % ( qnTech, res, fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and foAI.foAIstate.aggression > fo.aggression.cautious and not tech_is_complete(AIDependencies.PRO_SINGULAR_GEN) and tech_is_complete(AIDependencies.PRO_SOL_ORB_GEN)): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(AIDependencies.PRO_SINGULAR_GEN) sing_tech_list = [ pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req) ] sing_tech_list += [AIDependencies.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated + 1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 msg = "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d" % ( singTech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list ] if len(missing_prereqs ) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx - 18))
def _calculate_research_priority(): """Calculates the AI empire's demand for research.""" universe = fo.getUniverse() empire = fo.getEmpire() current_turn = fo.currentTurn() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) recent_enemies = [x for x in enemies_sighted if x > current_turn - 8] industry_priority = foAI.foAIstate.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_SENTIENT_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)] print "Research Milestones accomplished at turn %d: %s" % (current_turn, milestones_done) total_pp = empire.productionPoints total_rp = empire.resourceProduction(fo.resourceType.research) industry_surge = (foAI.foAIstate.character.may_surge_industry(total_pp, total_rp) and (((orb_gen_tech in research_queue_list[:2] or got_orb_gen) and state.have_gas_giant) or ((mgrav_prod_tech in research_queue_list[:2] or got_mgrav_prod) and state.have_asteroids)) and (state.get_number_of_colonies() < 12)) # get current industry production & Target owned_planet_ids = PlanetUtilsAI.get_owned_planets_by_empire(universe.planetIDs) planets = map(universe.getPlanet, owned_planet_ids) target_rp = sum(map(lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets)) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) style_index = foAI.foAIstate.character.preferred_research_cutoff([0, 1]) if foAI.foAIstate.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.PROD_AUTO_NAME)): # 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) print "Research Production (current/target) : ( %.1f / %.1f )" % (total_rp, target_rp) print "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
def generate_classic_research_orders(): """generate research orders""" empire = fo.getEmpire() empire_id = empire.empireID aistate = get_aistate() enemies_sighted = aistate.misc.get("enemies_sighted", {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() resource_production = empire.resourceProduction(fo.resourceType.research) completed_techs = sorted(list(get_completed_techs())) _print_reserch_order_header(resource_production, completed_techs) # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() total_rp = empire.resourceProduction(fo.resourceType.research) tech_turns_left = {} if research_queue_list: debug("Techs currently at head of Research Queue:") for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft this_tech = fo.getTech(element.tech) if not this_tech: warning("Can't retrieve tech ", element.tech) continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs ] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: debug( " %25s allocated %6.2f RP (%d turns left)-- unlockable items: %s ", element.tech, element.allocation, tech_turns_left[element.tech], unlocked_items, ) else: debug( " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s ", element.tech, element.allocation, missing_prereqs, unlocked_items, ) debug("") # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() <= 2) or ((total_rp - research_queue.totalSpent) > 0): research_index = get_research_index() if fo.currentTurn() == 1: # do only this one on first turn, to facilitate use of a turn-1 savegame for testing of alternate # research strategies new_tech = ["LRN_PHYS_BRAIN", "GRO_PLANET_ECOL"] else: new_tech = (TechsListsAI.sparse_galaxy_techs(research_index) if galaxy_is_sparse else TechsListsAI.primary_meta_techs(research_index)) debug("Empire %s (%d) is selecting research index %d", empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs + research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: error("Desired tech '%s' appears to not exist" % tech) continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base ] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs + [tech]) cum_cost = 0 debug(" Enqueued Tech: %20s \t\t %8s \t %s", "Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost debug(" Enqueued Tech: %20s \t\t %8.0f \t %8.0f", name, this_cost, cum_cost) else: warning(" Failed attempt to enqueued Tech: " + name) except: # noqa: E722 warning(" Failed attempt to enqueued Tech: " + name, exc_info=True) debug("\n\nAll techs:") debug("=" * 20) alltechs = fo.techs() print_in_columns(sorted(fo.techs()), columns=3) debug("\n\nAll unqueued techs:") debug("=" * 20) # coveredTechs = new_tech+completed_techs print_in_columns([tn for tn in alltechs if tn not in tech_base], columns=3) debug("") if fo.currentTurn() == 1: return if True: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if (aistate.character.may_research_tech_classic(def_tech) and def_tech not in research_queue_list[:5] and not tech_is_complete(def_tech)): res = fo.issueEnqueueTechOrder( def_tech, min(3, len(research_queue_list))) debug( "Empire is very defensive, so attempted to fast-track %s, got result %d", def_tech, res) if False: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list and aistate.character.may_research_tech_classic( "CON_CONC_CAMP"): insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list) - 10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list and aistate.character.may_research_tech_classic( "SHP_DEFLECTOR_SHIELD"): insert_idx = min( insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if (cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete(cc_tech) and aistate.character.may_research_tech_classic(cc_tech)): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) debug( "Empire is very aggressive, so attempted to fast-track %s, got result %d", cc_tech, res) elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup nest_tech = Dep.NEST_DOMESTICATION_TECH artif_minds = Dep.LRN_ARTIF_MINDS_1 if have_nest() and not tech_is_complete(nest_tech): if artif_minds in research_queue_list: insert_idx = 1 + research_queue_list.index(artif_minds) else: insert_idx = 1 res = fo.issueEnqueueTechOrder(nest_tech, insert_idx) num_techs_accelerated += 1 debug( "Have a monster nest, so attempted to fast-track %s, got result %d", nest_tech, res) research_queue_list = get_research_queue_techs() # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(aistate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = next( iter(aistate.colonisablePlanetIDs.items()))[1] if len(aistate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = next( iter(aistate.colonisableOutpostIDs.items()))[1] need_improved_scouting = best_colony_site_score < 150 or best_outpost_site_score < 200 if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d", "CON_ORBITAL_CON", res, ) elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("CON_METRO_INFRA")): for supply_tech in [ _s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech) ]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d", supply_tech, res, ) else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete( "SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2 + num_techs_accelerated] and tech_is_complete( "PRO_FUSION_GEN" ): if "CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" "CON_ORBITAL_CON", res, ) research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (have_ruins() and not tech_is_complete("LRN_XENOARCH") and aistate.character.may_research_tech_classic("LRN_XENOARCH")): if artif_minds in research_queue_list: insert_idx = 7 + research_queue_list.index(artif_minds) elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if not tech_is_complete( xenoTech ) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 debug( "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d", xenoTech, res, ) research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [ ("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_ADAPTIVE_AUTOMATION", "PRO_ADAPTIVE_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_ADAPTIVE_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_ADAPTIVE_AUTOMATION"]), ( "PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", [ "PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I" ], ), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [ 0, 1, 2, ]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: debug( "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s", move_tech, target_slot, target_index, num_techs_accelerated, ) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: fo.issueEnqueueTechOrder(move_tech, target_index) debug( "Research: To prioritize %s, have advanced %s to slot %d", tech, move_tech, target_index) target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if have_asteroids(): insert_idx = (num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index("GRO_SYMBIOTIC_BIO")) ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 debug( "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d", ast_tech, res, ) research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = ( (1 + insert_idx) if "LRN_FORCE_FIELD" not in research_queue_list else max( 1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1)) for ast_tech in [ "SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS" ]: if not tech_is_complete( ast_tech ) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 debug( "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d", ast_tech, res, ) research_queue_list = get_research_queue_techs() if have_gas_giant() and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = (0 if "PRO_FUSION_GEN" not in research_queue_list else (1 + research_queue_list.index("PRO_FUSION_GEN"))) forcefields_idx = (0 if "LRN_FORCE_FIELD" not in research_queue_list else (1 + research_queue_list.index("LRN_FORCE_FIELD"))) insert_idx = max( fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 debug( "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d", "PRO_ORBITAL_GEN", res, ) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and (not got_xeno_gen): most_adequate = 0 for specName in get_colony_builders(): environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [ fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids, ]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max( most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if (xg_tech not in research_queue_list[:1 + num_techs_accelerated] and not tech_is_complete(xg_tech) and aistate.character.may_research_tech_classic( xg_tech)): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 debug( "Empire has poor colonizers, so attempted to fast-track %s, got result %d", xg_tech, res, ) research_queue_list = get_research_queue_techs() # # check to accelerate translinguistics if True: # just to help with cold-folding / organization # planet is needed to determine the cost. Without a capital we have bigger problems anyway... if not tech_is_complete("LRN_TRANSLING_THT") and translators_wanted(): insert_idx = num_techs_accelerated for dt_ech in [ "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if (dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech) and aistate.character.may_research_tech_classic(dt_ech)): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire wants to build translators, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" debug(fmt_str, dt_ech, res, resource_production, empire.population(), fo.currentTurn()) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in get_empire_planets_by_species(): this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break pop_threshold = 100 if got_telepathy else 300 if empire.population() > pop_threshold: insert_idx = num_techs_accelerated for dt_ech in [ "LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT" ]: if (dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech) and aistate.character.may_research_tech_classic( dt_ech)): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" debug(fmt_str, dt_ech, res, resource_production, empire.population(), fo.currentTurn()) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if aistate.character.may_research_tech_classic("LRN_QUANT_NET") and ( population_with_research_focus() >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 debug( "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d", qnTech, res, fo.currentTurn(), ) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and aistate.character.may_research_tech_classic("PRO_SINGULAR_GEN") and not tech_is_complete(Dep.PRO_SINGULAR_GEN) and tech_is_complete("LRN_EVERYTHING")): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(Dep.PRO_SINGULAR_GEN) sing_tech_list = [ pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req) ] sing_tech_list += [Dep.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated + 1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 debug( "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d", singTech, res, ) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list ] if len(missing_prereqs ) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx - 18)) # TODO: Remove the following example code # Example/Test code for the new ShipDesigner functionality techs = [ "SHP_WEAPON_4_2", "SHP_TRANSSPACE_DRIVE", "SHP_INTSTEL_LOG", "SHP_ASTEROID_HULLS", "" ] for tech in techs: this_tech = fo.getTech(tech) if not this_tech: debug("Invalid Tech specified") continue unlocked_items = this_tech.unlockedItems unlocked_hulls = [] unlocked_parts = [] for item in unlocked_items: if item.type == fo.unlockableItemType.shipPart: debug("Tech %s unlocks a ShipPart: %s", tech, item.name) unlocked_parts.append(item.name) elif item.type == fo.unlockableItemType.shipHull: debug("Tech %s unlocks a ShipHull: %s", tech, item.name) unlocked_hulls.append(item.name) if not (unlocked_parts or unlocked_hulls): debug("No new ship parts/hulls unlocked by tech %s", tech) continue old_designs = ShipDesignAI.WarShipDesigner().optimize_design( consider_fleet_count=False) new_designs = ShipDesignAI.WarShipDesigner().optimize_design( additional_hulls=unlocked_hulls, additional_parts=unlocked_parts, consider_fleet_count=False) if not (old_designs and new_designs): # AI is likely defeated; don't bother with logging error message continue old_rating, old_pid, old_design_id, old_cost, old_stats = old_designs[ 0] old_design = fo.getShipDesign(old_design_id) new_rating, new_pid, new_design_id, new_cost, new_stats = new_designs[ 0] new_design = fo.getShipDesign(new_design_id) if new_rating > old_rating: debug("Tech %s gives access to a better design!", tech) debug("old best design: Rating %.5f", old_rating) debug("old design specs: %s - %s", old_design.hull, list(old_design.parts)) debug("new best design: Rating %.5f", new_rating) debug("new design specs: %s - %s", new_design.hull, list(new_design.parts)) else: debug( "Tech %s gives access to new parts or hulls but there seems to be no military advantage.", tech)
def _calculate_colonisation_priority(): """Calculates the demand for colony ships by colonisable planets.""" global allottedColonyTargets enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() total_pp = fo.getEmpire().productionPoints num_colonies = state.get_number_of_colonies() colony_growth_barrier = foAI.foAIstate.character.max_number_colonies() if num_colonies > colony_growth_barrier: return 0.0 colony_cost = AIDependencies.COLONY_POD_COST * (1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies) turns_to_build = 8 # TODO: check for susp anim pods, build time 10 mil_prio = foAI.foAIstate.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 = foAI.foAIstate.character.preferred_colonization_portion(allotted_portion) # if ( foAI.foAIstate.get_priority(AIPriorityType.PRIORITY_PRODUCTION_COLONISATION) # > 2 * foAI.foAIstate.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 = foAI.foAIstate.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 foAI.foAIstate.colonisablePlanetIDs.items() if min_score < score <= minimal_top] decent_opportunities = [species_name for (_, (score, species_name)) in foAI.foAIstate.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