def calculateIndustryPriority(): "calculates the demand for industry" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID # get current industry production & Target industryProduction = empire.resourceProduction(fo.resourceType.industry) ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry), planets) ) if fo.currentTurn() < 20: industryPriority = 20 # mid industry , high research at beginning of game to get easy gro tech elif fo.currentTurn() < 30: industryPriority = 25 # mid industry , mid research elif fo.currentTurn() < 40: industryPriority = 40 # high industry , mid research elif fo.currentTurn() < 50: industryPriority = 50 # high industry , mid research else: industryPriority = 60 # high industry , low-mid research # increase demand for industry industry production is low #industryPriority = 380 / (industryProduction + 0.001) print "" print "Industry Production (current/target) : ( %.1f / %.1f ) at turn %s"%(industryProduction, targetPP, fo.currentTurn()) print "Priority for Industry: " + str(industryPriority) return industryPriority
def getInvasionFleets(): "get invasion fleets" allInvasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) AIstate.invasionFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allInvasionFleetIDs) # get supplyable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) # get competitor planets exploredSystemIDs = empire.exploredSystemIDs exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) # print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs) empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) # print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) competitorPlanetIDs = list(set(allOwnedPlanetIDs) - set(empireOwnedPlanetIDs)) print "Competitor PlanetIDs: " + str(competitorPlanetIDs) print "" print "Invasion Targeted SystemIDs: " + str(AIstate.invasionTargetedSystemIDs) invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, empireID) allInvasionTargetedSystemIDs = PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs) # export invasion targeted systems for other AI modules AIstate.invasionTargetedSystemIDs = allInvasionTargetedSystemIDs print "Invasion Targeted PlanetIDs: " + str(invasionTargetedPlanetIDs) invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) if not invasionFleetIDs: print "Available Invasion Fleets: 0" else: print "Invasion FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION)) numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs)) print "Invasion Fleets Without Missions: " + str(numInvasionFleets) evaluatedPlanetIDs = list(set(competitorPlanetIDs) - set(invasionTargetedPlanetIDs)) # print "Evaluated PlanetIDs: " + str(evaluatedPlanetIDs) evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire) sortedPlanets = evaluatedPlanets.items() sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "" print "Invadable planetIDs:" for evaluationPair in sortedPlanets: print " ID|Score: " + str(evaluationPair) # export opponent planets for other AI modules AIstate.opponentPlanetIDs = sortedPlanets
def calculateResearchPriority(): "calculates the AI empire's demand for research" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete totalPP = empire.productionPoints totalRP = empire.resourceProduction(fo.resourceType.research) # get current industry production & Target ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets) ) if (fo.currentTurn() < 20) or not gotAlgo: researchPriority = 60 # mid industry , high research at beginning of game to get easy gro tech and to get research booster Algotrithmic Elegance elif fo.currentTurn() < 30: researchPriority = 30 # mid industry , mid research elif fo.currentTurn() < 40: researchPriority = 20 # high industry , low research else: researchPriority = 15 # high industry , low research print "" print "Research Production (current/target) : ( %.1f / %.1f )"%(totalRP, targetRP) print "Priority for Research: " + str(researchPriority) return researchPriority
def setCapitalIDResourceFocus(): "set resource focus of CapitalID planet" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) capitalID = PlanetUtilsAI.getCapital() topPriority = topResourcePriority() if topPriority == AIPriorityType.PRIORITY_RESOURCE_GROWTH: newFocus = AIFocusType.FOCUS_GROWTH for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION: newFocus = AIFocusType.FOCUS_INDUSTRY for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH: newFocus = AIFocusType.FOCUS_RESEARCH for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus)
def printResourcesPriority(): "calculate top resource priority" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) print "Resource Management:" print "" print "Resource Priorities:" resourcePriorities = {} for priorityType in getAIPriorityResourceTypes(): resourcePriorities[priorityType] = foAI.foAIstate.getPriority(priorityType) sortedPriorities = resourcePriorities.items() sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True) topPriority = -1 for evaluationPair in sortedPriorities: if topPriority < 0: topPriority = evaluationPair[0] print " ID|Score: " + str(evaluationPair) print " Top Resource Priority: " + str(topPriority) # what is the focus of available resource centers? print "" print "Planet Resources Foci:" for planetID in ownedPlanetIDs: planet = universe.getPlanet(planetID) planetPopulation = planet.currentMeterValue(fo.meterType.population) print " ID: " + str(planetID) + " Name: " + str(planet.name) + " Type: " + str(planet.type) + " Size: " + str(planet.size) + " Focus: " + str(planet.focus) + " Species: " + str(planet.speciesName) + " Population: " + str(planetPopulation)
def calculateResearchPriority(): "calculates the AI empire's demand for research" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID industryPriority = foAI.foAIstate.getPriority(EnumsAI.AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete researchQueueList = ResearchAI.getResearchQueueTechs() orbGenTech = "PRO_ORBITAL_GEN" totalPP = empire.productionPoints totalRP = empire.resourceProduction(fo.resourceType.research) industrySurge= (foAI.foAIstate.aggression > fo.aggression.cautious) and ( totalPP <(30*(foAI.foAIstate.aggression)) ) and (orbGenTech in researchQueueList[:3] or empire.getTechStatus(orbGenTech) == fo.techStatus.complete) # get current industry production & Target ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets) ) styleIndex = empireID%2 cutoffSets = [ [25, 45, 70 ], [35, 50, 70 ] ] cutoffs = cutoffSets[styleIndex ] settings = [ [2, .6, .4, .35 ], [1.4, .7, .4, .35 ] ][styleIndex ] if industrySurge and True: researchPriority = 0.2 * industryPriority else: if (fo.currentTurn() < cutoffs[0]) or not gotAlgo: researchPriority = settings[0] * industryPriority # high research at beginning of game to get easy gro tech and to get research booster Algotrithmic Elegance elif fo.currentTurn() < cutoffs[1]: researchPriority = settings[1] * industryPriority# med-high research elif fo.currentTurn() < cutoffs[2]: researchPriority = settings[2] * industryPriority # med-high industry else: researchQueue = list(empire.researchQueue) researchPriority = settings[3] * industryPriority # high industry , low research if len(researchQueue) == 0 : researchPriority = 0 # done with research elif len(researchQueue) <5 and researchQueue[-1].allocation > 0 : researchPriority = len(researchQueue) # barely not done with research elif len(researchQueue) <10 and researchQueue[-1].allocation > 0 : researchPriority = 4+ len(researchQueue) # almost done with research elif len(researchQueue) <20 and researchQueue[int(len(researchQueue)/2)].allocation > 0 : researchPriority = 0.5 * researchPriority # closing in on end of research elif len(researchQueue) <20: researchPriority = 0.7*researchPriority # high industry , low research print "" print "Research Production (current/target) : ( %.1f / %.1f )"%(totalRP, targetRP) print "Priority for Research: " + str(researchPriority) return researchPriority
def calculateResearchPriority(): "calculates the AI empire's demand for research" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete researchQueueList = getResearchQueueTechs() orbGenTech = "PRO_ORBITAL_GEN" totalPP = empire.productionPoints totalRP = empire.resourceProduction(fo.resourceType.research) industrySurge= (foAI.foAIstate.aggression > fo.aggression.cautious) and ( totalPP <(20*(foAI.foAIstate.aggression)) ) and (orbGenTech in researchQueueList[:2] or empire.getTechStatus(orbGenTech) == fo.techStatus.complete) # get current industry production & Target ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets) ) styleIndex = empireID%2 styleAdjustmentMap = {0:0, 1:0}#TODO: decide if I want to do anything with this styleAdjustment = styleAdjustmentMap.get( styleIndex, 0 ) cutoffs = [ [30, 40, 60 ], [35, 50, 70 ] ][styleIndex ] #1 doing better settings = [ [50, 40, 35, 30 ], [50, 40, 30, 25 ] ][styleIndex ] #cutoffs = [ [40, 65, 90 ], [40, 90, 150 ] ][styleIndex ] #1 doing better if industrySurge and False: researchPriority = 10+styleAdjustment else: if (fo.currentTurn() < cutoffs[0]) or not gotAlgo: researchPriority = settings[0] # mid industry , high research at beginning of game to get easy gro tech and to get research booster Algotrithmic Elegance elif fo.currentTurn() < cutoffs[1]: researchPriority = settings[1] +styleAdjustment# mid industry , mid research elif fo.currentTurn() < cutoffs[2]: researchPriority = settings[2]+styleAdjustment # high industry , low research else: researchQueue = list(empire.researchQueue) researchPriority = settings[3]+styleAdjustment # high industry , low research if len(researchQueue) == 0 : researchPriority = 0 # done with research elif len(researchQueue) <5 and researchQueue[-1].allocation > 0 : researchPriority = len(researchQueue) # barely not done with research elif len(researchQueue) <10 and researchQueue[-1].allocation > 0 : researchPriority = 2 # almost done with research elif len(researchQueue) <20 and researchQueue[int(len(researchQueue)/2)].allocation > 0 : researchPriority = 5 # closing in on end of research elif len(researchQueue) <20: researchPriority = 10 # high industry , low research print "" print "Research Production (current/target) : ( %.1f / %.1f )"%(totalRP, targetRP) print "Priority for Research: " + str(researchPriority) return researchPriority
def setGasGiantsResourceFocus(): "change resource focus of gas giants from farming to research" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) newFocus = AIFocusType.FOCUS_RESEARCH for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planet.type == fo.planetType.gasGiant and 'GRO_ORBIT_FARMING' in empire.availableTechs and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus)
def setAsteroidsResourceFocus(): "change resource focus of asteroids from farming to mining" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) newFocus = AIFocusType.FOCUS_INDUSTRY for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planet.type == fo.planetType.asteroids and 'GRO_ORBIT_FARMING' in empire.availableTechs and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus)
def getResourceTargetTotals(): universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) capitalID = PlanetUtilsAI.getCapital() # planet = universe.getPlanet(planetID) # if planet.currentMeterValue(fo.meterType.population) >0: planets = map(universe.getPlanet, empirePlanetIDs) planetMap = dict( zip( empirePlanetIDs, planets)) oldTargets.clear() oldTargets.update(newTargets) newTargets.clear() currentFocus.clear() currentOutput.clear() targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry), planets) ) targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets) ) newFocus= IFocus for pid in empirePlanetIDs: canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0 currentFocus[pid] = planetMap[pid].focus #if currentFocus[pid] == MFocus: # mtarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry) currentOutput.setdefault(pid, {} )[ IFocus] = planetMap[pid].currentMeterValue(fo.meterType.industry) currentOutput[pid][ RFocus] = planetMap[pid].currentMeterValue(fo.meterType.research) if canFocus: fo.issueChangeFocusOrder(pid, IFocus) #may not be able to take, but try universe.updateMeterEstimates(empirePlanetIDs) for pid in empirePlanetIDs: canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0 itarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry) rtarget=planetMap[pid].currentMeterValue(fo.meterType.targetResearch) newTargets.setdefault(pid, {}).setdefault(IFocus, (0, 0)) newTargets[pid][IFocus] = ( itarget, rtarget ) #if currentFocus[pid] == MFocus: # newTargets[pid][MFocus] = ( mtarget, rtarget ) if canFocus: fo.issueChangeFocusOrder(pid, RFocus) #may not be able to take, but try universe.updateMeterEstimates(empirePlanetIDs) for pid in empirePlanetIDs: canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0 itarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry) rtarget=planetMap[pid].currentMeterValue(fo.meterType.targetResearch) newTargets.setdefault(pid, {}).setdefault(RFocus, (0, 0)) newTargets[pid][RFocus] = ( itarget, rtarget ) if canFocus and currentFocus[pid] != RFocus: fo.issueChangeFocusOrder(pid, currentFocus[pid]) #put it back to what it was universe.updateMeterEstimates(empirePlanetIDs) return targetPP, targetRP
def setGeneralPlanetResourceFocus(): "set resource focus of planets except capitalID, asteroids, and gas giants" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) capitalID = [empire.capitalID] asteroids = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.asteroids) gasGiants = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.gasGiant) generalPlanetIDs = list(set(empirePlanetIDs) - (set(capitalID)|set(asteroids)|set(gasGiants))) topPriority = topResourcePriority() fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) if topPriority == AIPriorityType.PRIORITY_RESOURCE_FOOD: newFocus = AIFocusType.FOCUS_FARMING for planetID in generalPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_MINERALS: newFocus = AIFocusType.FOCUS_MINING for planetID in generalPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION: newFocus = AIFocusType.FOCUS_INDUSTRY for planetID in generalPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH: newFocus = AIFocusType.FOCUS_RESEARCH for planetID in generalPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus) else: focus = AIFocusType.FOCUS_FARMING if focus in planet.availableFoci: fo.issueChangeFocusOrder(planetID, focus)
def calculateIndustryPriority(): #currently only used to print status "calculates the demand for industry" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID # get current industry production & Target industryProduction = empire.resourceProduction(fo.resourceType.industry) ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry), planets) ) industryPriority = foAI.foAIstate.getPriority(EnumsAI.AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) print "" print "Industry Production (current/target) : ( %.1f / %.1f ) at turn %s"%(industryProduction, targetPP, fo.currentTurn()) print "Priority for Industry: " + str(industryPriority) return industryPriority
def printResourcesPriority(): "calculate top resource priority" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) print "Resource Management:" print "" print "Resource Priorities:" resourcePriorities = {} for priorityType in getAIPriorityResourceTypes(): resourcePriorities[priorityType] = foAI.foAIstate.getPriority(priorityType) sortedPriorities = resourcePriorities.items() sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True) topPriority = -1 for evaluationPair in sortedPriorities: if topPriority < 0: topPriority = evaluationPair[0] print " ResourcePriority |Score: %s | %s "%(AIPriorityTypeNames.name(evaluationPair[0]), evaluationPair[1]) # what is the focus of available resource centers? print "" warnings={} print "Planet Resources Foci:" for planetID in empirePlanetIDs: planet = universe.getPlanet(planetID) planetPopulation = planet.currentMeterValue(fo.meterType.population) maxPop = planet.currentMeterValue(fo.meterType.targetPopulation) if maxPop < 1 and planetPopulation >0: warnings[planet.name]=(planetPopulation, maxPop) statusStr = " ID: " + str(planetID) + " Name: % 18s -- % 6s % 8s "%(str(planet.name) , str(planet.size), str(planet.type) ) statusStr += " Focus: % 8s"%("_".join(str(planet.focus).split("_")[1:])[:8]) + " Species: " + str(planet.speciesName) + " Pop: %2d/%2d"%(planetPopulation, maxPop) print statusStr print "\n\nEmpire Totals:\nPopulation: %5d \nProduction: %5d\nResearch: %5d\n"%(empire.population(), empire.productionPoints, empire.resourceProduction(fo.resourceType.research)) if warnings != {}: for pname in warnings: mp, cp = warnings[pname] print "Population Warning! -- %s has unsustainable current pop %d -- target %d"%(pname, cp, mp ) print "" warnings.clear()
def topResourcePriority(): "calculate top resource priority" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) resourcePriorities = {} for priorityType in getAIPriorityResourceTypes(): resourcePriorities[priorityType] = foAI.foAIstate.getPriority(priorityType) sortedPriorities = resourcePriorities.items() sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True) topPriority = -1 for evaluationPair in sortedPriorities: if topPriority < 0: topPriority = evaluationPair[0] return topPriority
def setPlanetResourceFoci(): #+ "set resource focus of planets " global __timerFile print "\n============================" print "Collecting info to assess Planet Focus Changes\n" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID currentTurn = fo.currentTurn() freq = min(3, ( max(5, currentTurn-120) )/4.0)**(1.0/3) if ( abs(currentTurn - lastFociCheck[0] ) <1.5*freq) and ( random() < 1.0/freq ) : timer = 6*[time()] else: lastFociCheck[0]=currentTurn timer= [ time() ] # getPlanets empirePlanetIDs = list( PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) ) timer.append( time() ) #filter timer.append( time() ) #Priority #TODO: take into acct splintering of resource groups #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH) priorityRatio = float(rpPrio)/(ppPrio+0.0001) timer.append( time() ) # shuffle # not supporting Growth for general planets until also adding code to make sure would actually benefit #shuffle(generalPlanetIDs) timer.append( time() ) # targets planets = map(universe.getPlanet, empirePlanetIDs) planetMap = dict( zip( empirePlanetIDs, planets)) if useGrowth: for metab, metabIncPop in ColonisationAI.empireMetabolisms.items(): for special in [aspec for aspec in AIDependencies.metabolimBoostMap.get(metab, []) if aspec in ColonisationAI.availableGrowthSpecials]: rankedPlanets=[] for pid in ColonisationAI.availableGrowthSpecials[special]: planet = planetMap[pid] pop = planet.currentMeterValue(fo.meterType.population) if (pop > metabIncPop - planet.size) or (GFocus not in planet.availableFoci): #not enough benefit to lose local production, or can't put growth focus here continue for special2 in [ "COMPUTRONIUM_SPECIAL" ]: if special2 in planet.specials: break else: #didn't have any specials that would override interest in growth special print "Considering Growth Focus for %s (%d) with special %s; planet has pop %.1f and %s metabolism incremental pop is %.1f"%( planet.name, pid, special, pop, metab, metabIncPop) rankedPlanets.append( (pop, pid) ) if rankedPlanets == []: continue rankedPlanets.sort() print "Considering Growth Focus choice for special %s; possible planet pop, id pairs are %s"%(metab, rankedPlanets) for spSize, spPID in rankedPlanets: #index 0 should be able to set focus, but just in case... result = 1 curFocus = planet.focus if curFocus != GFocus: result = fo.issueChangeFocusOrder(spPID, GFocus) if result == 1: if spPID in empirePlanetIDs: del empirePlanetIDs[ empirePlanetIDs.index( spPID ) ] print "%s focus of planet %s (%d) at Growth Focus"%( ["set", "left" ][ curFocus == GFocus ] , planetMap[spPID].name, spPID) break else: print "failed setting focus of planet %s (%d) at Growth Focus; focus left at %s"%( planetMap[spPID].name, spPID, planetMap[spPID].focus) pp, rp = getResourceTargetTotals(empirePlanetIDs, planetMap) print "\n-----------------------------------------" print "Making Planet Focus Change Determinations\n" ratios = [] #for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that # include a bias to slightly discourage changing foci curTargetPP = 0.001 curTargetRP = 0.001 newFoci = {} timer.append( time() ) #loop hasForce = empire.getTechStatus("CON_FRC_ENRG_STRC") == fo.techStatus.complete for pid in newTargets: II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] CI, CR = currentOutput[pid][ IFocus], currentOutput[pid][ RFocus] #consider straddling balance range within which 1RP costs 1PP if True and (foAI.foAIstate.aggression >= fo.aggression.aggressive): if (CR<RR) and ( (CR-IR) >= (II-CI) ) and (priorityRatio > ( (curTargetRP+CR+1)/ max(0.001, curTargetPP +CI -1))): curTargetPP += CI -1 # curTargetRP += CR+1 newFoci[pid] = RFocus continue curTargetPP += II #icurTargets initially calculated by Industry focus, which will be our default focus curTargetRP += IR newFoci[pid] = IFocus #if foAI.foAIstate.aggression < fo.aggression.maniacal: # if currentFocus[pid] in [ IFocus, MFocus] : # II += min( 2, II /4.0 ) # elif currentFocus[pid] == RFocus: # RR += min( 2, RR/4.0 ) #calculate factor F at which II + F * RI == RI + F * RR =====> F = ( II-RI ) / (RR-IR) thisFactor = ( II-RI ) / max( 0.01, RR-IR) # don't let denominator be zero for planets where focus doesn't change RP if foAI.foAIstate.aggression >fo.aggression.aggressive: if currentOutput[pid][ IFocus] > II +RI - RR: thisFactor = min(thisFactor, 1.0 + thisFactor/10.0 ) ratios.append( (thisFactor, pid ) ) ctPP0 = curTargetPP ctRP0 = curTargetRP ratios.sort() printedHeader=False fociMap={IFocus:"Industry", RFocus:"Research", MFocus:"Mining", GFocus:"Growth"} gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete for ratio, pid in ratios: if priorityRatio < ( curTargetRP/ (curTargetPP + 0.0001)) : #we have enough RP if ratio < 1.1 and foAI.foAIstate.aggression >fo.aggression.cautious : #but wait, RP is still super cheap relative to PP, maybe will take more RP if priorityRatio < 1.5* ( curTargetRP/ (curTargetPP + 0.0001)) : #yeah, really a glut of RP, stop taking RP break else: #RP not super cheap & we have enough, stop taking it break II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] #if currentFocus[pid] == MFocus: # II = max( II, newTargets[pid][MFocus][0] ) if gotAlgo and ( (ratio > 2.0 and curTargetPP < 15) or (ratio > 2.5 and curTargetPP < 25 and II > 5) or (ratio > 3.0 and curTargetPP < 40 and II > 5) or (ratio > 4.0 and curTargetPP < 100 and II > 10) or ( (curTargetRP+RR-IR)/max(0.001, curTargetPP - II+RI) > 2* priorityRatio )): # we already have algo elegance and more RP would be too expensive, or overkill if not printedHeader: printedHeader=True print "Rejecting further Research Focus choices as too expensive:" print "%34s|%20s|%15s |%15s|%15s |%15s |%15s"%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," rejectedFocus ", " rejected target RP/PP ", "rejected RP-PP EQF") oldFocus=currentFocus[pid] cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP= newTargets[pid].get(RFocus, (0, 0)) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f | %.2f"%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[RFocus] , ntRP, ntPP , ratio) continue # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose if planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0: #only set to research if pop won't die out newFoci[pid] = RFocus curTargetRP += (RR-IR) curTargetPP -= (II-RI) print "============================" print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f ( %.1f / %.1f )"%(priorityRatio, rp/(pp+0.0001), rp, pp) print "Max Industry assignments would result in target RP/PP ratio of %.2f ( %.1f / %.1f )"%( ctRP0/ (ctPP0 + 0.0001), ctRP0, ctPP0 ) print "-------------------------------------" print "%34s|%20s|%15s |%15s|%15s |%15s "%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," newFocus ", " new target RP/PP ") totalChanged=0 for pid in newTargets: canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0 oldFocus=currentFocus[pid] newFocus = newFoci[pid] cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] if newFocus!= planetMap[pid].focus and newFocus in planetMap[pid].availableFoci: totalChanged+=1 result = fo.issueChangeFocusOrder(pid, newFocus) if result != 1: print "Trouble changing focus of planet %s (%d) to %s"%(planetMap[pid].name, pid, newFocus) otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP= newTargets[pid].get(newFocus, (0, 0)) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f "%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[newFocus] , ntRP, ntPP ) print "-------------------------------------\nFinal Ratio Target (turn %4d) RP/PP : %.2f ( %.1f / %.1f ) after %d Focus changes"%( fo.currentTurn(), curTargetRP/ (curTargetPP + 0.0001), curTargetRP, curTargetPP , totalChanged) aPP, aRP = empire.productionPoints, empire.resourceProduction(fo.resourceType.research) print "Current Output (turn %4d) RP/PP : %.2f ( %.1f / %.1f )"%(fo.currentTurn(), aRP/ (aPP + 0.0001), aRP, aPP ), "\n------------------------" timer.append( time() ) #end if doResourceTiming and __timerEntries==__timerEntries2: times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] timeFmt = "%30s: %8d msec " print "ResourcesAI Time Requirements:" for mod, modTime in zip(__timerEntries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if resourceTimerFile: print "len times: %d ; len entries: %d "%(len(times), len(__timerEntries)) resourceTimerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') resourceTimerFile.flush()
def setPlanetResourceFoci(): #+ "set resource focus of planets " newFoci = {} print "\n============================" print "Collecting info to assess Planet Focus Changes\n" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID currentTurn = fo.currentTurn() freq = min(3, ( max(5, currentTurn-80) )/4.0)**(1.0/3) if limitAssessments and ( abs(currentTurn - lastFociCheck[0] ) <1.5*freq) and ( random() < 1.0/freq ) : timer = 6*[time()] else: lastFociCheck[0]=currentTurn timer= [ time() ] # getPlanets empirePlanetIDs = list( PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) ) timer.append( time() ) #filter timer.append( time() ) #Priority #TODO: take into acct splintering of resource groups #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH) priorityRatio = float(rpPrio)/(ppPrio+0.0001) timer.append( time() ) # shuffle # not supporting Growth for general planets until also adding code to make sure would actually benefit #shuffle(generalPlanetIDs) timer.append( time() ) # targets planets = map(universe.getPlanet, empirePlanetIDs) planetMap.clear() planetMap.update( zip( empirePlanetIDs, planets)) if useGrowth: for metab, metabIncPop in ColonisationAI.empireMetabolisms.items(): for special in [aspec for aspec in AIDependencies.metabolimBoostMap.get(metab, []) if aspec in ColonisationAI.availableGrowthSpecials]: rankedPlanets=[] for pid in ColonisationAI.availableGrowthSpecials[special]: planet = planetMap[pid] cur_focus = planet.focus pop = planet.currentMeterValue(fo.meterType.population) if (pop > metabIncPop - 2*planet.size) or (GFocus not in planet.availableFoci): #not enough benefit to lose local production, or can't put growth focus here continue for special2 in [ "COMPUTRONIUM_SPECIAL" ]: if special2 in planet.specials: break else: #didn't have any specials that would override interest in growth special print "Considering Growth Focus for %s (%d) with special %s; planet has pop %.1f and %s metabolism incremental pop is %.1f"%( planet.name, pid, special, pop, metab, metabIncPop) if cur_focus == GFocus: pop -=4 #discourage changing current focus to minimize focus-changing penalties rankedPlanets.append( (pop, pid, cur_focus) ) if rankedPlanets == []: continue rankedPlanets.sort() print "Considering Growth Focus choice for special %s; possible planet pop, id pairs are %s"%(metab, rankedPlanets) for spSize, spPID, cur_focus in rankedPlanets: #index 0 should be able to set focus, but just in case... result = 1 if cur_focus != GFocus: result = fo.issueChangeFocusOrder(spPID, GFocus) if result == 1: newFoci[pid] = GFocus if spPID in empirePlanetIDs: del empirePlanetIDs[ empirePlanetIDs.index( spPID ) ] print "%s focus of planet %s (%d) at Growth Focus"%( ["set", "left" ][ cur_focus == GFocus ] , planetMap[spPID].name, spPID) break else: print "failed setting focus of planet %s (%d) at Growth Focus; focus left at %s"%( planetMap[spPID].name, spPID, planetMap[spPID].focus) for pid in empirePlanetIDs: planet = planetMap[pid] if "COMPUTRONIUM_SPECIAL" in planet.specials:#TODO: ensure only one (extremely rarely needed) curFocus = planet.focus if RFocus not in planet.availableFoci: continue newFoci[pid] = RFocus result=0 if curFocus != RFocus: result = fo.issueChangeFocusOrder(pid, RFocus) if result == 1: universe.updateMeterEstimates(empirePlanetIDs) if curFocus == RFocus or result==1: print "%s focus of planet %s (%d) (with Computronium Moon) at Research Focus"%( ["set", "left" ][ curFocus == RFocus ] , planetMap[pid].name, pid) if pid in empirePlanetIDs: del empirePlanetIDs[ empirePlanetIDs.index( pid ) ] elif ( ([bld.buildingTypeName for bld in map( universe.getObject, planet.buildingIDs) if bld.buildingTypeName in ["BLD_CONC_CAMP", "BLD_CONC_CAMP_REMNANT"]] != [] ) or ( [ ccspec for ccspec in planet.specials if ccspec in [ "CONC_CAMP_MASTER_SPECIAL", "CONC_CAMP_SLAVE_SPECIAL" ] ] != [] )): if IFocus not in planet.availableFoci: continue curFocus = planet.focus newFoci[pid] = IFocus result=0 if curFocus != IFocus: result = fo.issueChangeFocusOrder(pid, IFocus) if result == 1: print ("Tried setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, got result %d and focus %s"% ( newFoci[pid], planet.name, pid, planet.speciesName, curFocus, result, planetMap[pid].focus )) universe.updateMeterEstimates(empirePlanetIDs) if (result != 1) or planetMap[pid].focus != IFocus: newplanet=universe.getPlanet(pid) print ("Error: Failed setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, but new planet copy shows %s"% ( newFoci[pid], planetMap[pid].name, pid, planetMap[pid].speciesName, planetMap[pid].focus, newplanet.focus )) if curFocus == IFocus or result==1: print "%s focus of planet %s (%d) (with Concentration Camps/Remnants) at Industry Focus"%( ["set", "left" ][ curFocus == IFocus ] , planetMap[pid].name, pid) if pid in empirePlanetIDs: del empirePlanetIDs[ empirePlanetIDs.index( pid ) ] #pp, rp = getResourceTargetTotals(empirePlanetIDs, planetMap) pp, rp = getResourceTargetTotals(planetMap.keys()) print "\n-----------------------------------------" print "Making Planet Focus Change Determinations\n" ratios = [] #for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that # include a bias to slightly discourage changing foci curTargetPP = 0.001 curTargetRP = 0.001 timer.append( time() ) #loop has_force = empire.getTechStatus("CON_FRC_ENRG_STRC") == fo.techStatus.complete preset_ids = set(planetMap.keys()) - set(empirePlanetIDs) ctPP0, ctRP0 = 0, 0 for pid in preset_ids: nPP, nRP = newTargets.get(pid, {}).get( planetMap[pid].focus, [0, 0] ) curTargetPP += nPP curTargetRP += nRP iPP, iRP = newTargets.get(pid, {}).get( IFocus, [0, 0] ) ctPP0 += iPP ctRP0 += iRP id_set = set(empirePlanetIDs) for adj_round in [1, 2, 3, 4]: maxi_ratio = ctRP0 / max ( 0.01, ctPP0 ) #should only change between rounds 1 and 2 for pid in list(id_set): if round == 1: #tally max Industry iPP, iRP = newTargets.get(pid, {}).get( IFocus, [0, 0] ) ctPP0 += iPP ctRP0 += iRP continue II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] CI, CR = currentOutput[pid][ IFocus], currentOutput[pid][ RFocus] research_penalty = (currentFocus[pid] != RFocus) #calculate factor F at which II + F * IR == RI + F * RR =====> F = ( II-RI ) / (RR-IR) thisFactor = ( II-RI ) / max( 0.01, RR-IR) # don't let denominator be zero for planets where focus doesn't change RP planet = planetMap[pid] if round == 2: #take research at planets with very cheap research if (maxi_ratio < priorityRatio) and (curTargetRP < priorityRatio * ctPP0) and (thisFactor <=1.0): curTargetPP += RI # curTargetRP += RR newFoci[pid] = RFocus id_set.discard(pid) continue if (round == 3): #take research at planets where can do reasonable balance if (has_force) or (foAI.foAIstate.aggression < fo.aggression.aggressive) or (curTargetRP >= priorityRatio * ctPP0): continue pop = planet.currentMeterValue(fo.meterType.population) t_pop = planet.currentMeterValue(fo.meterType.targetPopulation) #if AI is aggressive+, and this planet in range where temporary Research focus can get an additional RP at cost of 1 PP, and still need some RP, then do it if (pop < t_pop - 5): continue if ( CI > II + 8) or (( (RR>II) or ((RR-CR)>=1+2*research_penalty)) and ((RR-IR)>=3) and ( (CR-IR) >= 0.7*((II-CI)(1+0.1*research_penalty) ) )): curTargetPP += CI -1 - research_penalty# curTargetRP += CR+1 newFoci[pid] = RFocus id_set.discard(pid) continue #round == 4 assume default IFocus curTargetPP += II #icurTargets initially calculated by Industry focus, which will be our default focus curTargetRP += IR newFoci[pid] = IFocus ratios.append( (thisFactor, pid ) ) ratios.sort() printedHeader=False fociMap={IFocus:"Industry", RFocus:"Research", MFocus:"Mining", GFocus:"Growth"} gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete for ratio, pid in ratios: do_research = False#(newFoci[pid]==RFocus) if (priorityRatio < ( curTargetRP/ (curTargetPP + 0.0001))) and not do_research: #we have enough RP if ratio < 1.1 and foAI.foAIstate.aggression >fo.aggression.cautious : #but wait, RP is still super cheap relative to PP, maybe will take more RP if priorityRatio < 1.5* ( curTargetRP/ (curTargetPP + 0.0001)) : #yeah, really a glut of RP, stop taking RP break else: #RP not super cheap & we have enough, stop taking it break II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] #if currentFocus[pid] == MFocus: # II = max( II, newTargets[pid][MFocus][0] ) if do_research or (gotAlgo and ( (ratio > 2.0 and curTargetPP < 15) or (ratio > 2.5 and curTargetPP < 25 and II > 5) or (ratio > 3.0 and curTargetPP < 40 and II > 5) or (ratio > 4.0 and curTargetPP < 100 and II > 10) or ( (curTargetRP+RR-IR)/max(0.001, curTargetPP - II+RI) > 2* priorityRatio ))): # we already have algo elegance and more RP would be too expensive, or overkill if not printedHeader: printedHeader=True print "Rejecting further Research Focus choices as too expensive:" print "%34s|%20s|%15s |%15s|%15s |%15s |%15s"%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," rejectedFocus ", " rejected target RP/PP ", "rejected RP-PP EQF") oldFocus=currentFocus[pid] cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP= newTargets[pid].get(RFocus, (0, 0)) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f | %.2f"%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[RFocus] , ntRP, ntPP , ratio) continue # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose #if planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0: #only set to research if pop won't die out newFoci[pid] = RFocus curTargetRP += (RR-IR) curTargetPP -= (II-RI) print "============================" print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f ( %.1f / %.1f )"%(priorityRatio, rp/(pp+0.0001), rp, pp) print "Max Industry assignments would result in target RP/PP ratio of %.2f ( %.1f / %.1f )"%( ctRP0/ (ctPP0 + 0.0001), ctRP0, ctPP0 ) print "-------------------------------------" print "%34s|%20s|%15s |%15s|%15s |%15s "%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," newFocus ", " new target RP/PP ") totalChanged=0 for id_set in empirePlanetIDs, preset_ids: for pid in id_set: canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0 oldFocus=currentFocus[pid] newFocus = newFoci.get(pid, IFocus) cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP = otPP, otRP if newFocus != oldFocus and newFocus in planetMap[pid].availableFoci: #planetMap[pid].focus totalChanged+=1 if newFocus != planetMap[pid].focus: result = fo.issueChangeFocusOrder(pid, newFocus) if result == 1: ntPP, ntRP= newTargets[pid].get(newFocus, (0, 0)) else: print "Trouble changing focus of planet %s (%d) to %s"%(planetMap[pid].name, pid, newFocus) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f "%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[newFocus] , ntRP, ntPP ) print "-------------------------------------" print "-------------------------------------\nFinal Ratio Target (turn %4d) RP/PP : %.2f ( %.1f / %.1f ) after %d Focus changes"%( fo.currentTurn(), curTargetRP/ (curTargetPP + 0.0001), curTargetRP, curTargetPP , totalChanged) aPP, aRP = empire.productionPoints, empire.resourceProduction(fo.resourceType.research) print "Current Output (turn %4d) RP/PP : %.2f ( %.1f / %.1f )"%(fo.currentTurn(), aRP/ (aPP + 0.0001), aRP, aPP ), "\n------------------------" timer.append( time() ) #end if doResourceTiming and timer_entries==__timerEntries2: times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] timeFmt = "%30s: %8d msec " print "ResourcesAI Time Requirements:" for mod, modTime in zip(timer_entries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if resourceTimerFile: print "len times: %d ; len entries: %d "%(len(times), len(timer_entries)) resourceTimerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') resourceTimerFile.flush()
def getInvasionFleets(): "get invasion fleets" times=[] tasks = [] times.append( time() ) tasks.append("init") allInvasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) AIstate.invasionFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allInvasionFleetIDs) # get supplyable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() #capitalID = empire.capitalID homeworld=None if capitalID: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: speciesName = "" homeworldName=" no remaining homeworld " homeSystemID = -1 fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) primeInvadableSystemIDs = set(ColonisationAI.annexableSystemIDs) primeInvadablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(primeInvadableSystemIDs) # get competitor planets exploredSystemIDs = empire.exploredSystemIDs exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() visiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(visibleSystemIDs) if homeSystemID != -1: accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if (sysID != -1 ) and universe.systemsConnected(sysID, homeSystemID, empireID) ] else: print "Invasion Warning: this empire has no identifiable homeworld, will therefor treat all visible planets as accessible." accessibleSystemIDs = visibleSystemIDs #TODO: check if any troop ships still owned, use their system as home system acessiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(accessibleSystemIDs) print "Accessible Systems: " + str(PlanetUtilsAI.sysNameIDs(accessibleSystemIDs)) print #allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(acessiblePlanetIDs)#need these for unpopulated outposts # print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs) allPopulatedPlanets=PlanetUtilsAI.getPopulatedPlanetIDs(acessiblePlanetIDs)#need this for natives print "All Visible and accessible Populated PlanetIDs (including this empire's): " + str(PlanetUtilsAI.planetNameIDs(allPopulatedPlanets)) print print "Prime Invadable Target Systems: " + str(PlanetUtilsAI.sysNameIDs(primeInvadableSystemIDs)) print empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) # print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) invadablePlanetIDs = set(primeInvadablePlanetIDs).intersection(set(allOwnedPlanetIDs).union(allPopulatedPlanets) - set(empireOwnedPlanetIDs)) print "Prime Invadable PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(invadablePlanetIDs)) print "" print "Current Invasion Targeted SystemIDs: " + str(PlanetUtilsAI.sysNameIDs(AIstate.invasionTargetedSystemIDs)) invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, empireID) invasionTargetedPlanetIDs.extend( getInvasionTargetedPlanetIDs(universe.planetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, empireID)) allInvasionTargetedSystemIDs = set(PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs)) print "Current Invasion Targeted PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(invasionTargetedPlanetIDs)) invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) if not invasionFleetIDs: print "Available Invasion Fleets: 0" else: print "Invasion FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION)) numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs)) print "Invasion Fleets Without Missions: " + str(numInvasionFleets) times.append( time() ) tasks.append( "gathering initial info" ) availablePP = {} for el in empire.planetsWithAvailablePP: #keys are sets of ints; data is doubles avail_pp = el.data() for pid in el.key(): availablePP[pid] = avail_pp if len (invadablePlanetIDs) > 0: #print "Evaluating Troop Bases (SpaceInvaders) for %s"%(invadablePlanetIDs) pass for pid in invadablePlanetIDs: #TODO: reorganize planet = universe.getPlanet(pid) if not planet: continue sysID = planet.systemID sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, empireID)).get(fo.visibility.partial, -9999) planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(pid, empireID)).get(fo.visibility.partial, -9999) if (planetPartialVisTurn < sysPartialVisTurn): #print "rejecting %s due to stealth"%planet.name continue for pid2 in ColonisationAI.empireSpeciesSystems.get(sysID, {}).get('pids', []): if availablePP.get(pid2, 0) < 2: #TODO: improve troop base PP sufficiency determination #print "rejecting %s due to insufficient avail PP"%planet.name break planet2 = universe.getPlanet(pid2) if not planet2: continue if (pid not in foAI.foAIstate.qualifyingTroopBaseTargets) and (planet2.speciesName in ColonisationAI.empireShipBuilders): #print "Adding %s to Troop Bases (SpaceInvaders) potential target list, from %s"%(planet.name, planet2.name) foAI.foAIstate.qualifyingTroopBaseTargets.setdefault(pid, [pid2, -1]) break for pid in list(foAI.foAIstate.qualifyingTroopBaseTargets): planet = universe.getPlanet(pid) if planet and planet.owner == empireID: del foAI.foAIstate.qualifyingTroopBaseTargets[pid] reserved_troop_base_targets = [] secureAIFleetMissions = foAI.foAIstate.getAIFleetMissionsWithAnyMissionTypes([EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE]) #print "considering possible troop bases at %s" % (foAI.foAIstate.qualifyingTroopBaseTargets.keys()) for pid in (set(foAI.foAIstate.qualifyingTroopBaseTargets.keys()) - set(invasionTargetedPlanetIDs)): #TODO: consider overriding standard invasion mission planet = universe.getPlanet(pid) if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1: reserved_troop_base_targets.append(pid) if planet: allInvasionTargetedSystemIDs.add( planet.systemID ) continue #already building for here loc = foAI.foAIstate.qualifyingTroopBaseTargets[pid][0] this_score, p_troops = evaluateInvasionPlanet(pid, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire, secureAIFleetMissions, False) if (planet.currentMeterValue(fo.meterType.shield)) > 0: continue bestShip, colDesign, buildChoices = ProductionAI.getBestShipInfo(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_ORBITAL_INVASION, loc) if not bestShip: #print "Error: no troop base can be built at ", PlanetUtilsAI.planetNameIDs([loc]) continue #print "selecting ", PlanetUtilsAI.planetNameIDs([loc]), " to build Orbital troop bases" n_bases = math.ceil((p_troops+1) / 2)#TODO: reconsider this +1 safety factor retval = fo.issueEnqueueShipProductionOrder(bestShip, loc) print "Enqueueing %d Troop Bases at %s for %s"%( n_bases, PlanetUtilsAI.planetNameIDs([loc]), PlanetUtilsAI.planetNameIDs([pid])) if retval !=0: allInvasionTargetedSystemIDs.add( planet.systemID ) reserved_troop_base_targets.append(pid) foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] = loc fo.issueChangeProductionQuantityOrder(empire.productionQueue.size -1, 1, int(n_bases)) res=fo.issueRequeueProductionOrder(empire.productionQueue.size -1, 0) times.append( time() ) tasks.append( "planning troop base production" ) #TODO: check if any invasionTargetedPlanetIDs need more troops assigned evaluatedPlanetIDs = list(set(invadablePlanetIDs) - set(invasionTargetedPlanetIDs) - set(reserved_troop_base_targets) ) print "Evaluating potential invasions, PlanetIDs: " + str(evaluatedPlanetIDs) evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire) sortedPlanets = [(pid, pscore, ptroops) for (pid, (pscore, ptroops)) in evaluatedPlanets.items() ] sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) sortedPlanets = [(pid, pscore%10000, ptroops) for (pid, pscore, ptroops) in sortedPlanets ] times.append( time() ) tasks.append( "evaluating %d target planets"%(len(evaluatedPlanetIDs)) ) print "" if sortedPlanets: print "Invadable planets\nIDs, ID | Score | Name | Race | Troops" for pid, pscore, ptroops in sortedPlanets: planet = universe.getPlanet(pid) if planet: print "%6d | %6d | %16s | %16s | %d"%(pid, pscore, planet.name, planet.speciesName, ptroops) else: print "%6d | %6d | Error: invalid planet ID"%(pid, pscore) else: print "No Invadable planets identified" sortedPlanets = [(pid, pscore, ptroops) for (pid, pscore, ptroops) in sortedPlanets if pscore > 0] # export opponent planets for other AI modules AIstate.opponentPlanetIDs = [pid for pid, pscore, trp in sortedPlanets] AIstate.invasionTargets = sortedPlanets # export invasion targeted systems for other AI modules AIstate.invasionTargetedSystemIDs = list(allInvasionTargetedSystemIDs) times.append( time() ) tasks.append( "total processing" ) for t_index in range(1, len(times)-1): print "getInvasionFleets(): %40s took %d msec"%(tasks[t_index], int(1000*(times[t_index]-times[t_index-1]))) print "getInvasionFleets(): %40s took %d msec"%(tasks[-1], int(1000*(times[-1]-times[0])))
def getColonyFleets(): "get colony fleets" allColonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION) AIstate.colonyFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allColonyFleetIDs) # get suppliable systems and planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = empire.capitalID homeworld = universe.getPlanet(capitalID) speciesName = homeworld.speciesName species = fo.getSpecies(speciesName) fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) print "" print " fleetSupplyableSystemIDs: " + str(list(fleetSupplyableSystemIDs)) print " fleetSupplyablePlanetIDs: " + str(fleetSupplyablePlanetIDs) print "" # get outpost and colonization planets exploredSystemIDs = empire.exploredSystemIDs print "Explored SystemIDs: " + str(list(exploredSystemIDs)) exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) print "Explored PlanetIDs: " + str(exploredPlanetIDs) print "" allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs) empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) unpopulatedPlanetIDs = list(set(exploredPlanetIDs) - set(allOwnedPlanetIDs)) print "Unpopulated PlanetIDs: " + str(unpopulatedPlanetIDs) print "" colonyTargetedPlanetIDs = getColonyTargetedPlanetIDs( universe.planetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, empireID ) print "Colony Targeted PlanetIDs: " + str(colonyTargetedPlanetIDs) colonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION) if not colonyFleetIDs: print "Available Colony Fleets: 0" else: print "Colony FleetIDs: " + str( FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION) ) numColonyFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(colonyFleetIDs)) print "Colony Fleets Without Missions: " + str(numColonyFleets) print "" outpostTargetedPlanetIDs = getOutpostTargetedPlanetIDs( universe.planetIDs, AIFleetMissionType.FLEET_MISSION_OUTPOST, empireID ) print "Outpost Targeted PlanetIDs: " + str(outpostTargetedPlanetIDs) outpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST) if not outpostFleetIDs: print "Available Outpost Fleets: 0" else: print "Outpost FleetIDs: " + str( FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST) ) numOutpostFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(outpostFleetIDs)) print "Outpost Fleets Without Missions: " + str(numOutpostFleets) evaluatedColonyPlanetIDs = list(set(unpopulatedPlanetIDs) - set(colonyTargetedPlanetIDs)) # print "Evaluated Colony PlanetIDs: " + str(evaluatedColonyPlanetIDs) evaluatedOutpostPlanetIDs = list(set(unpopulatedPlanetIDs) - set(outpostTargetedPlanetIDs)) # print "Evaluated Outpost PlanetIDs: " + str(evaluatedOutpostPlanetIDs) evaluatedColonyPlanets = assignColonisationValues( evaluatedColonyPlanetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, fleetSupplyablePlanetIDs, species, empire, ) removeLowValuePlanets(evaluatedColonyPlanets) sortedPlanets = evaluatedColonyPlanets.items() sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "" print "Settleable Colony PlanetIDs:" for evaluationPair in sortedPlanets: print " ID|Score: " + str(evaluationPair) print "" # export planets for other AI modules AIstate.colonisablePlanetIDs = sortedPlanets # get outpost fleets allOutpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST) AIstate.outpostFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allOutpostFleetIDs) evaluatedOutpostPlanets = assignColonisationValues( evaluatedOutpostPlanetIDs, AIFleetMissionType.FLEET_MISSION_OUTPOST, fleetSupplyablePlanetIDs, species, empire ) removeLowValuePlanets(evaluatedOutpostPlanets) sortedOutposts = evaluatedOutpostPlanets.items() sortedOutposts.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "Settleable Outpost PlanetIDs:" for evaluationPair in sortedOutposts: print " ID|Score: " + str(evaluationPair) print "" # export outposts for other AI modules AIstate.colonisableOutpostIDs = sortedOutposts
def getInvasionFleets(): "get invasion fleets" allInvasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) AIstate.invasionFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allInvasionFleetIDs) # get supplyable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() #capitalID = empire.capitalID homeworld=None if capitalID: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: speciesName = "" homeworldName=" no remaining homeworld " homeSystemID = -1 fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) primeInvadableSystemIDs = set(ColonisationAI.annexableSystemIDs) primeInvadablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(primeInvadableSystemIDs) # get competitor planets exploredSystemIDs = empire.exploredSystemIDs exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() visiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(visibleSystemIDs) accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] acessiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(accessibleSystemIDs) #allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(acessiblePlanetIDs) # print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs) allPopulatedPlanets=PlanetUtilsAI.getPopulatedPlanetIDs(acessiblePlanetIDs) print "All Visible and accessible Populated PlanetIDs (including this empire's): " + str(PlanetUtilsAI.planetNameIDs(allPopulatedPlanets)) empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) # print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) invadablePlanetIDs = set(primeInvadablePlanetIDs).intersection(set(allPopulatedPlanets) - set(empireOwnedPlanetIDs)) print "Prime Invadable PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(invadablePlanetIDs)) print "" print "Current Invasion Targeted SystemIDs: " + str(PlanetUtilsAI.sysNameIDs(AIstate.invasionTargetedSystemIDs)) invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, empireID) allInvasionTargetedSystemIDs = PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs) # export invasion targeted systems for other AI modules AIstate.invasionTargetedSystemIDs = allInvasionTargetedSystemIDs print "Current Invasion Targeted PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(invasionTargetedPlanetIDs)) invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) if not invasionFleetIDs: print "Available Invasion Fleets: 0" else: print "Invasion FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION)) numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs)) print "Invasion Fleets Without Missions: " + str(numInvasionFleets) evaluatedPlanetIDs = list(set(invadablePlanetIDs) - set(invasionTargetedPlanetIDs)) print "Evaluating potential invasions, PlanetIDs: " + str(evaluatedPlanetIDs) evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire) sortedPlanets = [(pid, pscore, ptroops) for (pid, (pscore, ptroops)) in evaluatedPlanets.items() ] sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) sortedPlanets = [(pid, pscore%10000, ptroops) for (pid, pscore, ptroops) in sortedPlanets ] print "" if sortedPlanets: print "Invadable planets\nIDs, ID | Score | Name | Race | Troops" for pid, pscore, ptroops in sortedPlanets: planet = universe.getPlanet(pid) if planet: print "%6d | %6d | %16s | %16s | %d"%(pid, pscore, planet.name, planet.speciesName, ptroops) else: print "%6d | %6d | Error: invalid planet ID"%(pid, pscore) else: print "No Invadable planets identified" # export opponent planets for other AI modules AIstate.opponentPlanetIDs = [pid for pid, pscore, trp in sortedPlanets] AIstate.invasionTargets = sortedPlanets
def getInvasionFleets(): "get invasion fleets" allInvasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) AIstate.invasionFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allInvasionFleetIDs) # get supplyable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() #capitalID = empire.capitalID homeworld=None if capitalID: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: speciesName = "" homeworldName=" no remaining homeworld " homeSystemID = -1 fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) primeInvadableSystemIDs1 = set([]) primeInvadableSystemIDs = set([]) print "Current Fleet Supplyable Systems: ", sysNameIDs(empire.fleetSupplyableSystemIDs) for sysID in empire.fleetSupplyableSystemIDs: primeInvadableSystemIDs.add(sysID) for nID in universe.getImmediateNeighbors(sysID, empireID): primeInvadableSystemIDs.add(nID) primeInvadableSystemIDs1.add(nID) primeInvadableSystemIDs1.difference_update(empire.fleetSupplyableSystemIDs) print "First Ring of invadable systems: ", sysNameIDs(primeInvadableSystemIDs1) if empire.getTechStatus("CON_ORBITAL_CON") == fo.techStatus.complete: primeInvadableSystemIDs2 = set([]) for sysID in list(primeInvadableSystemIDs1): for nID in universe.getImmediateNeighbors(sysID, empireID): primeInvadableSystemIDs2.add(nID) primeInvadableSystemIDs2.difference_update(primeInvadableSystemIDs) print "Second Ring of invadable systems: ", sysNameIDs(primeInvadableSystemIDs2) primeInvadableSystemIDs.update(primeInvadableSystemIDs2) primeInvadableSystemIDs3 = set([]) if foAI.foAIstate.aggression > 1: for sysID in list(primeInvadableSystemIDs2): for nID in universe.getImmediateNeighbors(sysID, empireID): primeInvadableSystemIDs3.add(nID) primeInvadableSystemIDs3.difference_update(primeInvadableSystemIDs) print "Third Ring of invadable systems: ", sysNameIDs(primeInvadableSystemIDs3) primeInvadableSystemIDs.update(primeInvadableSystemIDs3) primeInvadablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(primeInvadableSystemIDs) # get competitor planets exploredSystemIDs = empire.exploredSystemIDs exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() visiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(visibleSystemIDs) accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] acessiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(accessibleSystemIDs) #allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(acessiblePlanetIDs) # print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs) allPopulatedPlanets=PlanetUtilsAI.getPopulatedPlanetIDs(acessiblePlanetIDs) print "All Visible and accessible Populated PlanetIDs (including this empire's): " + str(planetNameIDs(allPopulatedPlanets)) empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) # print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) invadablePlanetIDs = set(primeInvadablePlanetIDs).intersection(set(allPopulatedPlanets) - set(empireOwnedPlanetIDs)) print "Prime Invadable PlanetIDs: " + str(planetNameIDs(invadablePlanetIDs)) print "" print "Invasion Targeted SystemIDs: " + str(sysNameIDs(AIstate.invasionTargetedSystemIDs)) invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, empireID) allInvasionTargetedSystemIDs = PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs) # export invasion targeted systems for other AI modules AIstate.invasionTargetedSystemIDs = allInvasionTargetedSystemIDs print "Invasion Targeted PlanetIDs: " + str(planetNameIDs(invasionTargetedPlanetIDs)) invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) if not invasionFleetIDs: print "Available Invasion Fleets: 0" else: print "Invasion FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION)) numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs)) print "Invasion Fleets Without Missions: " + str(numInvasionFleets) evaluatedPlanetIDs = list(set(invadablePlanetIDs) - set(invasionTargetedPlanetIDs)) print "Evaluating potential invasions, PlanetIDs: " + str(evaluatedPlanetIDs) evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire) sortedPlanets = [(pid, pscore, ptroops) for (pid, (pscore, ptroops)) in evaluatedPlanets.items() ] sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "" if sortedPlanets: print "Invadable planetIDs, ID | Score | Race | Troops | Name:" for pid, pscore, ptroops in sortedPlanets: planet = universe.getPlanet(pid) if planet: print "%6d | %6d | %s | %s | %d"%(pid, pscore, planet.name, planet.speciesName, ptroops) else: print "%6d | %6d | Error: invalid planet ID"%(pid, pscore) else: print "No Invadable planets identified" # export opponent planets for other AI modules AIstate.opponentPlanetIDs = [pid for pid, pscore, trp in sortedPlanets] AIstate.invasionTargets = sortedPlanets
def setPlanetResourceFoci(): "set resource focus of planets except capitalID, asteroids, and gas giants" global __timerFile print "\n============================" print "Collecting info to assess Planet Focus Changes\n" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID currentTurn = fo.currentTurn() freq = (1.0 + currentTurn/4.0)**(1.0/3) if random() > 1.0/freq: timer = 6*[time()] else: timer= [ time() ] # getPlanets empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) timer.append( time() ) #filter timer.append( time() ) #Priority #TODO: take into acct splintering of resource groups #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH) priorityRatio = float(rpPrio)/(ppPrio+0.0001) timer.append( time() ) # shuffle # not supporting Growth for general planets until also adding code to make sure would actually benefit #shuffle(generalPlanetIDs) timer.append( time() ) # targets pp, rp = getResourceTargetTotals() planets = map(universe.getPlanet, empirePlanetIDs) planetMap = dict( zip( empirePlanetIDs, planets)) print "\n-----------------------------------------" print "Making Planet Focus Change Determinations\n" ratios = [] #for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that # include a bias to slightly discourage changing foci curTargetPP = 0 curTargetRP = 0 newFoci = {} timer.append( time() ) #loop hasForce = empire.getTechStatus("CON_FRC_ENRG_STRC") == fo.techStatus.complete for pid in newTargets: II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] if currentFocus[pid] == MFocus: II = max( II, newTargets[pid][MFocus][0] ) curTargetPP += II #icurTargets initially calculated by Industry focus, which will be our default focus curTargetRP += IR newFoci[pid] = IFocus if foAI.foAIstate.aggression < 4: if currentFocus[pid] in [ IFocus, MFocus] : II += min( 2, II /4.0 ) elif currentFocus[pid] == RFocus: RR += min( 2, RR/4.0 ) #calculate factor F at which II + F * RI == RI + F * RR =====> F = ( II-RI ) / (RR-IR) thisFactor = ( II-RI ) / max( 0.01, RR-IR) # don't let denominator be zero for planets where focus doesn't change RP if foAI.foAIstate.aggression >3: if currentOutput[pid][ IFocus] > II +RI - RR: thisFactor = min(thisFactor, 1.0 + thisFactor/10.0 ) ratios.append( (thisFactor, pid ) ) ctPP0 = curTargetPP ctRP0 = curTargetRP ratios.sort() printedHeader=False fociMap={IFocus:"Industry", RFocus:"Research", MFocus:"Mining", GFocus:"Growth"} gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete for ratio, pid in ratios: if priorityRatio < ( curTargetRP/ (curTargetPP + 0.0001)) : #we have enough RP if ratio < 1.1 and foAI.foAIstate.aggression >1 : #but wait, RP is still super cheap relative to PP, maybe will take more RP if priorityRatio < 1.5* ( curTargetRP/ (curTargetPP + 0.0001)) : #yeah, really a glut of RP, stop taking RP break else: #RP not super cheap & we have enough, stop taking it break II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] if currentFocus[pid] == MFocus: II = max( II, newTargets[pid][MFocus][0] ) if gotAlgo and ( (ratio > 2.0 and curTargetPP < 15) or (ratio > 2.5 and curTargetPP < 25 and II > 5) or (ratio > 3.0 and curTargetPP < 40 and II > 5) or (ratio > 4.0 and curTargetPP < 100 and II > 10) or ( (curTargetRP+RR-IR)/max(0.001, curTargetPP - II+RI) > 2* priorityRatio )): # we already have algo elegance and more RP would be too expensive, or overkill if not printedHeader: printedHeader=True print "Rejecting further Research Focus choices as too expensive:" print "%34s|%20s|%15s |%15s|%15s |%15s |%15s"%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," rejectedFocus ", " rejected target RP/PP ", "rejected RP-PP EQF") oldFocus=currentFocus[pid] cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP= newTargets[pid].get(RFocus, (0, 0)) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f | %.2f"%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[RFocus] , ntRP, ntPP , ratio) continue # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose newFoci[pid] = RFocus curTargetRP += (RR-IR) curTargetPP -= (II-RI) print "============================" print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f ( %.1f / %.1f )"%(priorityRatio, rp/(pp+0.0001), rp, pp) print "Max Industry assignments would result in target RP/PP ratio of %.2f ( %.1f / %.1f )"%( ctRP0/ (ctPP0 + 0.0001), ctRP0, ctPP0 ) print "-------------------------------------" print "%34s|%20s|%15s |%15s|%15s |%15s "%(" Planet ", " current RP/PP ", " current target RP/PP ", "current Focus "," newFocus ", " new target RP/PP ") totalChanged=0 for pid in newTargets: oldFocus=currentFocus[pid] changeFocus=False newFocus = newFoci[pid] cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus] if newFocus==RFocus and oldFocus!=RFocus: changeFocus = True elif newFocus == IFocus: if ( MFocus in planetMap[pid].availableFoci ) and ( newTargets[pid].setdefault(MFocus, (25, IR))[0] > newTargets[pid][IFocus][0]): newFocus=MFocus if newFocus !=oldFocus: changeFocus = True else: pass #not supporting growth focus yet if changeFocus: totalChanged+=1 fo.issueChangeFocusOrder(pid, newFocus) otPP, otRP= newTargets[pid].get(oldFocus, (0, 0)) ntPP, ntRP= newTargets[pid].get(newFocus, (0, 0)) print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f | cF: %8s | nF: %8s | cT: %5.1f / %5.1f "%(pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[newFocus] , ntRP, ntPP ) print "-------------------------------------\nFinal Ratio Target (turn %4d) RP/PP : %.2f ( %.1f / %.1f ) after %d Focus changes"%( fo.currentTurn(), curTargetRP/ (curTargetPP + 0.0001), curTargetRP, curTargetPP , totalChanged) aPP, aRP = empire.productionPoints, empire.resourceProduction(fo.resourceType.research) print "Current Output (turn %4d) RP/PP : %.2f ( %.1f / %.1f )"%(fo.currentTurn(), aRP/ (aPP + 0.0001), aRP, aPP ), "\n------------------------" timer.append( time() ) #end if doResourceTiming and __timerEntries==__timerEntries2: times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] timeFmt = "%30s: %8d msec " print "ResourcesAI Time Requirements:" for mod, modTime in zip(__timerEntries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if resourceTimerFile: print "len times: %d ; len entries: %d "%(len(times), len(__timerEntries)) resourceTimerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') resourceTimerFile.flush()
def calculateResearchPriority(): "calculates the AI empire's demand for research" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID industryPriority = foAI.foAIstate.getPriority(EnumsAI.AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete got_quant = empire.getTechStatus("LRN_QUANT_NET") == fo.techStatus.complete researchQueueList = ResearchAI.getResearchQueueTechs() orbGenTech = "PRO_ORBITAL_GEN" got_orb_gen = (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete) got_solar_gen = (empire.getTechStatus("PRO_SOL_ORB_GEN") == fo.techStatus.complete) totalPP = empire.productionPoints totalRP = empire.resourceProduction(fo.resourceType.research) industrySurge= (foAI.foAIstate.aggression > fo.aggression.cautious) and ( totalPP <(30*(foAI.foAIstate.aggression)) ) and (orbGenTech in researchQueueList[:3] or empire.getTechStatus(orbGenTech) == fo.techStatus.complete) # get current industry production & Target ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) planets = map(universe.getPlanet, ownedPlanetIDs) targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch), planets) ) styleIndex = (empireID%3)%2 cutoffSets = [ [25, 45, 70 ], [35, 50, 70 ] ] cutoffs = cutoffSets[styleIndex ] settings = [ [1.4, .7, .4, .35 ], [2.0, 1.0, .6, .35 ] ][styleIndex ] if industrySurge and True: researchPriority = 0.2 * industryPriority else: if (fo.currentTurn() < cutoffs[0]) or (not gotAlgo) or ((styleIndex ==0) and not got_orb_gen): researchPriority = settings[0] * industryPriority # high research at beginning of game to get easy gro tech and to get research booster Algotrithmic Elegance elif (not got_orb_gen) or (fo.currentTurn() < cutoffs[1]) : researchPriority = settings[1] * industryPriority# med-high research elif (fo.currentTurn() < cutoffs[2]): researchPriority = settings[2] * industryPriority # med-high industry else: researchQueue = list(empire.researchQueue) researchPriority = settings[3] * industryPriority # high industry , low research if len(researchQueue) == 0 : researchPriority = 0 # done with research elif len(researchQueue) <5 and researchQueue[-1].allocation > 0 : researchPriority = len(researchQueue) # barely not done with research elif len(researchQueue) <10 and researchQueue[-1].allocation > 0 : researchPriority = 4+ len(researchQueue) # almost done with research elif len(researchQueue) <20 and researchQueue[int(len(researchQueue)/2)].allocation > 0 : researchPriority = 0.5 * researchPriority # closing in on end of research elif len(researchQueue) <20: researchPriority = 0.7*researchPriority # high industry , low research if ( ((empire.getTechStatus("SHP_WEAPON_2_4") == fo.techStatus.complete) or (empire.getTechStatus("SHP_WEAPON_4_1") == fo.techStatus.complete)) and (empire.getTechStatus("PRO_SENTIENT_AUTOMATION") == fo.techStatus.complete) ): industry_factor = [ [0.25, 0.2], [0.3, 0.25] ][styleIndex ] researchPriority = min(researchPriority, industry_factor[got_solar_gen]*industryPriority) if got_quant: researchPriority = min(researchPriority + 0.1*industryPriority, researchPriority * 1.3) researchPriority = int(researchPriority) print "" print "Research Production (current/target) : ( %.1f / %.1f )"%(totalRP, targetRP) print "Priority for Research: %d (new target ~ %d RP)"%(researchPriority, totalPP * researchPriority/industryPriority) return researchPriority
def getMilitaryFleets(milFleetIDs=None, tryReset=True, round="Main"): "get armed military fleets" global MilitaryAllocations, totMilRating universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() if capitalID == None: homeworld=None else: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: homeSystemID=-1 if milFleetIDs !=None: allMilitaryFleetIDs = milFleetIDs else: allMilitaryFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY ) if tryReset and ((fo.currentTurn()+empireID) % 10 ==0) and round=="Main": tryAgain(allMilitaryFleetIDs, tryReset=False, round = round+" Reset") milShips = 0 for fid in allMilitaryFleetIDs: milShips += foAI.foAIstate.fleetStatus.get(fid, {}).get('nships', 0) thisTotMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), allMilitaryFleetIDs ) ) if "Main" in round: totMilRating = thisTotMilRating print "==================================================" print "%s Round Total Military Rating: %d"%(round, totMilRating) print "---------------------------------" foAI.foAIstate.militaryRating=totMilRating milFleetIDs = list( FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allMilitaryFleetIDs)) availMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), milFleetIDs ) ) if "Main" in round: print "==================================================" print "%s Round Available Military Rating: %d"%(round, availMilRating) print "---------------------------------" remainingMilRating = availMilRating allocations = [] allocationGroups={} if milFleetIDs == []: if "Main" in round: MilitaryAllocations = [] return [] #for each system, get total rating of fleets assigned to it alreadyAssignedRating={} assignedAttack={} assignedHP={} for sysID in universe.systemIDs: assignedAttack[sysID]=0 assignedHP[sysID]=0 for fleetID in [fid for fid in allMilitaryFleetIDs if fid not in milFleetIDs]: aiFleetMission = foAI.foAIstate.getAIFleetMission(fleetID) sysTargets= [] for aiFleetMissionType in aiFleetMission.getAIMissionTypes(): aiTargets = aiFleetMission.getAITargets(aiFleetMissionType) for aiTarget in aiTargets: sysTargets.extend(aiTarget.getRequiredSystemAITargets()) if not sysTargets: #shouldn't really be possible continue lastSys = sysTargets[-1].getTargetID() # will count this fleet as assigned to last system in target list assignedAttack[lastSys] += foAI.foAIstate.getRating(fleetID).get('attack', 0) assignedHP[lastSys] += foAI.foAIstate.getRating(fleetID).get('health', 0) for sysID in universe.systemIDs: mydefenses = foAI.foAIstate.systemStatus.get(sysID, {}).get( 'mydefenses', {} ) mypattack = mydefenses.get('attack', 0) myphealth = mydefenses.get('health', 0) alreadyAssignedRating[sysID] = ( assignedAttack[sysID] + mypattack ) * ( assignedHP[sysID] + myphealth ) # get systems to defend capitalID = PlanetUtilsAI.getCapital() if capitalID != None: capitalPlanet = universe.getPlanet(capitalID) else: capitalPlanet=None #TODO: if no owned planets try to capture one! if capitalPlanet: capitalSysID = capitalPlanet.systemID else: # should be rare, but so as to not break code below, pick a randomish mil-centroid system capitalSysID=None #unless we can find one to use systemDict = {} for fleetID in allMilitaryFleetIDs: status = foAI.foAIstate.fleetStatus.get(fleetID, None) if status is not None: sysID = status['sysID'] if len( list( universe.getSystem(sysID).planetIDs ) ) ==0: continue systemDict[sysID] = systemDict.get( sysID, 0) + status.get('rating', {}).get('overall', 0) rankedSystems = sorted( [(val, sysID) for sysID, val in systemDict.items() ] ) if rankedSystems: capitalSysID = rankedSystems[-1][-1] else: try: capitalSysID = foAI.foAIstate.fleetStatus.items()[0][1]['sysID'] except: pass if False: if fo.currentTurn() < 20: threatBias = 0 elif fo.currentTurn() < 40: threatBias = 10 elif fo.currentTurn() < 60: threatBias = 80 elif fo.currentTurn() < 80: threatBias = 200 else: threatBias = 400 else: threatBias = 0 safetyFactor = [ 4.0, 3.0, 1.5, 1.0, 1.0, 0.95 ][foAI.foAIstate.aggression] topTargetPlanets = [pid for pid, pscore, trp in AIstate.invasionTargets[:PriorityAI.allottedInvasionTargets] if pscore > 20] + [pid for pid, pscore in foAI.foAIstate.colonisablePlanetIDs[:10] if pscore > 20] topTargetSystems = [] for sysID in AIstate.invasionTargetedSystemIDs + PlanetUtilsAI.getSystems( topTargetPlanets ): if sysID not in topTargetSystems: topTargetSystems.append(sysID) #doing this rather than set, to preserve order # allocation format: ( sysID, newAllocation, takeAny, maxMultiplier ) #================================ #--------Capital Threat ---------- capitalThreat = safetyFactor*(2* threatBias +sum( [ foAI.foAIstate.systemStatus[capitalSysID][thrtKey] for thrtKey in ['totalThreat', 'neighborThreat']] )) neededRating = ratingNeeded(1.4*capitalThreat, alreadyAssignedRating[capitalSysID]) newAlloc=0 if tryReset: if (neededRating > 0.5*availMilRating) : tryAgain(allMilitaryFleetIDs) return if neededRating > 0: newAlloc = min(remainingMilRating, neededRating ) allocations.append( ( capitalSysID, newAlloc, True, 2*capitalThreat) ) allocationGroups.setdefault('capitol', []).append( ( capitalSysID, newAlloc, True, 2*capitalThreat) ) remainingMilRating -= newAlloc if "Main" in round or newAlloc >0: print "Empire Capital System: (%d) %s -- threat : %d, military allocation: existing: %d ; new: %d"%(capitalSysID, universe.getSystem(capitalSysID).name , capitalThreat, alreadyAssignedRating[capitalSysID], newAlloc) print "-----------------" #================================ #--------Empire Occupied Systems ---------- empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) empireOccupiedSystemIDs = list( set(PlanetUtilsAI.getSystems(empirePlanetIDs)) - set([capitalSysID] ) ) if "Main" in round: print "Empire-Occupied Systems: %s"%( [ "| %d %s |"%(eoSysID, universe.getSystem(eoSysID).name) for eoSysID in empireOccupiedSystemIDs ] ) print "-----------------" newAlloc=0 if len( empireOccupiedSystemIDs ) > 0: ocSysTotThreat = [ ( oSID, threatBias +safetyFactor*sum( [ foAI.foAIstate.systemStatus.get(oSID, {}).get(thrtKey, 0) for thrtKey in ['totalThreat', 'neighborThreat']] )) for oSID in empireOccupiedSystemIDs ] totocSysThreat = sum( [thrt for sid, thrt in ocSysTotThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in ocSysTotThreat] ) allocationFactor = min( 1.5, remainingMilRating /max(0.01, ( totocSysThreat -totCurAlloc) )) ocSysAlloc = 0 for sid, thrt in ocSysTotThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.4*thrt, curAlloc) if (neededRating > 0.8*(remainingMilRating )) and tryReset: tryAgain(allMilitaryFleetIDs) return thisAlloc=0 if ( neededRating>0 ) and remainingMilRating > 0: thisAlloc = max(0, min( neededRating, 0.5*availMilRating, remainingMilRating)) newAlloc+=thisAlloc allocations.append( (sid, thisAlloc, True, 2*thrt) ) allocationGroups.setdefault('occupied', []).append( (sid, thisAlloc, True, 2*thrt) ) remainingMilRating -= thisAlloc ocSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Provincial Occupied system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "Provincial Empire-Occupied Sytems under total threat: %d -- total mil allocation: existing %d ; new: %d"%(totocSysThreat, totCurAlloc, ocSysAlloc ) print "-----------------" #================================ #--------Top Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = topTargetSystems if "Main" in round: print "Top Colony and Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('totalThreat', 0)+0.5*foAI.foAIstate.systemStatus.get(oSID, {}).get('neightborThreat', 0) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.4*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= alreadyAssignedRating[sid] > 0 if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) maxAlloc = safetyFactor*3*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) newAlloc+=thisAlloc allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('topTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Top Colony and Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" #================================ #--------Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = [sysID for sysID in set( PlanetUtilsAI.getSystems(AIstate.opponentPlanetIDs)) if sysID not in topTargetSystems] if "Main" in round: print "Other Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('totalThreat', 0)+0.5*foAI.foAIstate.systemStatus.get(oSID, {}).get('neighborThreat', 0) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.4*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= alreadyAssignedRating[sid] > 0 if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('otherTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [sysID for sysID in list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs)) if sysID not in topTargetSystems] if "Main" in round: print "Other Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(threatBias +foAI.foAIstate.systemStatus.get(oSID, {}).get('totalThreat', 0)+0.5*foAI.foAIstate.systemStatus.get(oSID, {}).get('neighborThreat', 0) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) newAlloc=0 for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.2*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= alreadyAssignedRating[sid] > 0 if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('otherTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Other Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [] targetableIDs = ColonisationAI.annexableSystemIDs.union( empire.fleetSupplyableSystemIDs ) for sysID in AIstate.opponentSystemIDs: if sysID in targetableIDs: otherTargetedSystemIDs.append(sysID) else: for nID in universe.getImmediateNeighbors(sysID, empireID): if nID in targetableIDs: otherTargetedSystemIDs.append(sysID) break if "Main" in round: print "Blockade Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('totalThreat', 0)+ 0.5*foAI.foAIstate.systemStatus.get(oSID, {}).get('neighborThreat', 0) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) newAlloc=0 for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.2*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= alreadyAssignedRating[sid] > 0 if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('otherTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Blockade Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Blockade Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" currentMilSystems = [sid for sid, alloc, takeAny, mm in allocations ] interiorIDs = list( foAI.foAIstate.expInteriorSystemIDs) interiorTargets1 = (targetableIDs.union(interiorIDs)).difference( currentMilSystems ) interiorTargets = [sid for sid in interiorTargets1 if ( (threatBias + foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0) >0.8*alreadyAssignedRating[sid] ) ) ] if "Main" in round: print "" print "Other Empire-Proximal Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in interiorTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len(interiorTargets) >0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('totalThreat', 0)) ) for oSID in interiorTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.2*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= alreadyAssignedRating[sid] > 0 if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('otherTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Other interior system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Other Interior Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" elif "Main" in round: print "-----------------" print "No Other Interior Systems with fleet threat " print "-----------------" monsterDens=[] #exploTargetIDs, _ = ExplorationAI.getCurrentExplorationInfo(verbose=False) exploTargetIDs=[] if "Main" in round: print "" print "Exploration-targeted Systems: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in exploTargetIDs ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len(exploTargetIDs) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in exploTargetIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) if availMilRating <1125: maxMilRating = availMilRating else: maxMilRating = 0.5*availMilRating for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.2*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= False if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('exploreTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Exploration-targeted %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Exploration-targeted s under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] currentMilSystems = [sid for sid, alloc, takeAny, multiplier in allocations if alloc > 0 ] borderTargets1 = [sid for sid in accessibleSystemIDs if ( ( sid not in currentMilSystems )) ] borderTargets = [sid for sid in borderTargets1 if ( ( threatBias +foAI.foAIstate.systemStatus.get(sid, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(sid, {}).get('planetThreat', 0) > 0.8*alreadyAssignedRating[sid] )) ] if "Main" in round: print "" print "Empire-Accessible Systems not yet allocated military: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID) and universe.getSystem(sysID).name) for sysID in borderTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len(borderTargets) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) for oSID in borderTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=alreadyAssignedRating[sid] neededRating = ratingNeeded( 1.2*thrt, curAlloc) thisAlloc=0 #only record more allocation for this invasion if we already started or have enough rating available takeAny= False if ( neededRating>0 ) and (remainingMilRating > neededRating or takeAny): thisAlloc = max(0, min( neededRating, remainingMilRating)) newAlloc+=thisAlloc maxAlloc = safetyFactor*2*max( foAI.foAIstate.systemStatus.get(sid, {}).get('totalThreat', 0), foAI.foAIstate.systemStatus.get(sid, {}).get('neightborThreat', 0)) allocations.append( (sid, thisAlloc, takeAny , maxAlloc) ) allocationGroups.setdefault('accessibleTargets', []).append( (sid, thisAlloc, takeAny , maxAlloc) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Other Empire-Accessible system %4d ( %10s ) has local biased threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" print "Other Empire-Accessible Systems under total biased threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" elif "Main" in round: print "-----------------" print "No Other Empire-Accessible Systems with biased local threat " print "-----------------" #monster den treatment probably unnecessary now if "Main" in round: print "" print "Big-Monster Dens: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in monsterDens ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety newAlloc=0 if len(monsterDens) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) ) ) for oSID in monsterDens ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 2* thrt: thisAlloc = int(0.99999 + (thrt-curAlloc)*1.5) newAlloc+=thisAlloc allocations.append( (sid, thisAlloc, False, 5) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc if "Main" in round or thisAlloc >0: print "Monster Den %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) if "Main" in round or newAlloc >0: print "-----------------" if remainingMilRating <=6: newAllocations = [ (sid, alc, alc, ta) for (sid, alc, ta, mm) in allocations ] else: #oldAllocations = dict( [ (entry[0], entry ) for entry in allocations ] ) try: totAlloc = sum( [alloc for sid, alloc, takeAny, maxAlloc in allocations ] ) except: print "error unpacking sid, alloc, takeAny, maxAlloc from ", allocations factor =(2.0* remainingMilRating ) / ( totAlloc + 0.1) #print "Remaining military strength allocation %d will be allocated as %.1f %% surplus allocation to top current priorities"%(remainingMilRating, 100*factor) print "%s Round Remaining military strength allocation %d will be allocated as surplus allocation to top current priorities"%(round, remainingMilRating) newAllocations = [] for cat in ['capitol', 'topTargets', 'otherTargets', 'accessibleTargets', 'occupied', 'exploreTargets']: for sid, alloc, takeAny, maxAlloc in allocationGroups.get(cat, []): if remainingMilRating <= 0 : newAllocations.append( ( sid, alloc, alloc, takeAny ) ) else: newRating = min(remainingMilRating+alloc, max(alloc, ratingNeeded( maxAlloc, alreadyAssignedRating[sid]) ) ) newAllocations.append( ( sid, newRating, alloc, takeAny ) ) remainingMilRating -= ( newRating - alloc ) if "Main" in round: MilitaryAllocations = newAllocations minMilAllocations = dict( [ (sid, alloc) for sid, alloc, takeAny, mm in allocations ] ) print "------------------------------\nFinal %s Round Military Allocations: %s \n-----------------------"%(round, dict( [ (sid, alloc) for sid, alloc, minalloc, takeAny in newAllocations ] ) ) # export military systems for other AI modules if "Main" in round: AIstate.militarySystemIDs = list( set([sid for sid, alloc, minalloc, takeAny in newAllocations]).union( [sid for sid in alreadyAssignedRating if alreadyAssignedRating[sid]>0 ] )) else: AIstate.militarySystemIDs = list( set([sid for sid, alloc, minalloc, takeAny in newAllocations]).union( AIstate.militarySystemIDs) ) return newAllocations
def getMilitaryFleets(tryReset=True): "get armed military fleets" global MilitaryAllocations, totMilRating universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() if capitalID == None: homeworld=None else: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: homeSystemID=-1 allMilitaryFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY ) if tryReset and ((fo.currentTurn()+empireID) % 10 ==0): tryAgain(allMilitaryFleetIDs) totMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), allMilitaryFleetIDs ) ) milShips = 0 for fid in allMilitaryFleetIDs: milShips += foAI.foAIstate.fleetStatus.get(fid, {}).get('nships', 0) print "==================================================" print "Total Military Rating: %d"%totMilRating print "---------------------------------" foAI.foAIstate.militaryRating=totMilRating milFleetIDs = list( FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allMilitaryFleetIDs)) availMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), milFleetIDs ) ) print "==================================================" print "Available Military Rating: %d"%availMilRating print "---------------------------------" remainingMilRating = availMilRating allocations = [] if milFleetIDs == []: MilitaryAllocations = [] return alreadyAssignedRating={} for sysID in universe.systemIDs: alreadyAssignedRating[sysID]=0 for fleetID in [fid for fid in allMilitaryFleetIDs if fid not in milFleetIDs]: aiFleetMission = foAI.foAIstate.getAIFleetMission(fleetID) sysTargets= [] for aiFleetMissionType in aiFleetMission.getAIMissionTypes(): aiTargets = aiFleetMission.getAITargets(aiFleetMissionType) for aiTarget in aiTargets: sysTargets.extend(aiTarget.getRequiredSystemAITargets()) if not sysTargets: #shouldn't really be possible continue lastSys = sysTargets[-1].getTargetID() # will count this fleet as assigned to last system in target list alreadyAssignedRating[lastSys] += foAI.foAIstate.getRating(fleetID).get('overall', 0) #TODO: would preferably tally attack and health and take product # get systems to defend capitalID = PlanetUtilsAI.getCapital() if capitalID != None: capitalPlanet = universe.getPlanet(capitalID) else: capitalPlanet=None #TODO: if no owned planets try to capture one! if capitalPlanet: capitalSysID = capitalPlanet.systemID else: # should be rare, but so as to not break code below, pick a randomish mil-centroid system systemDict = {} for fleetID in allMilitaryFleetIDs: status = foAI.foAIstate.fleetStatus.get(fleetID, None) if status is not None: sysID = status['sysID'] if len( list( universe.getSystem(sysID).planetIDs ) ) ==0: continue systemDict[sysID] = systemDict.get( sysID, 0) + status.get('rating', {}).get('overall', 0) rankedSystems = sorted( [(val, sysID) for sysID, val in systemDict.items() ] ) if rankedSystems: capitalSysID = rankedSystems[-1][-1] else: capitalSysID = foAI.foAIstate.fleetStatus.items()[0]['sysID'] if fo.currentTurn() < 20: threatBias = 0 elif fo.currentTurn() < 40: threatBias = 10 elif fo.currentTurn() < 60: threatBias = 80 elif fo.currentTurn() < 80: threatBias = 200 else: threatBias = 400 threatBias = 0 safetyFactor = [ 4.0, 3.0, 1.5, 1.0, 1.0, 0.95 ][foAI.foAIstate.aggression] topTargetPlanets = [pid for pid, pscore, trp in AIstate.invasionTargets[:PriorityAI.allottedInvasionTargets] if pscore > 20] + [pid for pid, pscore in foAI.foAIstate.colonisablePlanetIDs[:10] if pscore > 20] topTargetSystems = [] for sysID in PlanetUtilsAI.getSystems( topTargetPlanets ): if sysID not in topTargetSystems: topTargetSystems.append(sysID) #doing this rather than set, to preserve order # allocation format: ( sysID, newAllocation, takeAny, maxMultiplier ) #================================ #--------Capital Threat ---------- capitalThreat = safetyFactor*(2* threatBias +sum( [ foAI.foAIstate.systemStatus[capitalSysID][thrtKey] for thrtKey in [tkey for tkey in foAI.foAIstate.systemStatus.get(capitalSysID, {}).keys() if 'Threat' in tkey]] )) newAlloc=0 if tryReset: if (capitalThreat > 0.5*(availMilRating+0.8*alreadyAssignedRating[capitalSysID]) ) : tryAgain(allMilitaryFleetIDs) return if capitalThreat > 0.8*alreadyAssignedRating[capitalSysID]: newAlloc = min(remainingMilRating, int( 0.999 + 1.2*(capitalThreat- 0.8*alreadyAssignedRating[capitalSysID]) ) ) allocations.append( ( capitalSysID, newAlloc, True, 3) ) remainingMilRating -= newAlloc print "Empire Capital System: (%d) %s -- threat : %d, military allocation: existing: %d ; new: %d"%(capitalSysID, universe.getSystem(capitalSysID).name , capitalThreat, alreadyAssignedRating[capitalSysID], newAlloc) print "-----------------" #================================ #--------Empire Occupied Systems ---------- empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) empireOccupiedSystemIDs = list( set(PlanetUtilsAI.getSystems(empirePlanetIDs)) - set([capitalSysID] ) ) print "Empire-Occupied Systems: %s"%( [ "| %d %s |"%(eoSysID, universe.getSystem(eoSysID).name) for eoSysID in empireOccupiedSystemIDs ] ) print "-----------------" if len( empireOccupiedSystemIDs ) > 0: ocSysTotThreat = [ ( oSID, threatBias +safetyFactor*sum( [ foAI.foAIstate.systemStatus.get(oSID, {}).get(thrtKey, 0) for thrtKey in ['fleetThreat', 'monsterThreat','planetThreat', 'neighborThreat']] ) ) for oSID in empireOccupiedSystemIDs ] totocSysThreat = sum( [thrt for sid, thrt in ocSysTotThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in ocSysTotThreat] ) allocationFactor = min( 1.2, remainingMilRating /max(0.01, ( totocSysThreat -totCurAlloc) )) ocSysAlloc = 0 for sid, thrt in ocSysTotThreat: curAlloc=0.8*alreadyAssignedRating[sid] if (thrt > 0.8*(remainingMilRating+curAlloc )) and tryReset: tryAgain(allMilitaryFleetIDs) return thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: thisAlloc = max(0, min( min( int(0.99999 + (thrt-curAlloc)*allocationFactor ), 0.5*availMilRating) , remainingMilRating)) allocations.append( (sid, thisAlloc, True, 2) ) remainingMilRating -= thisAlloc ocSysAlloc += thisAlloc print "Provincial Empire-Occupied Sytems under total threat: %d -- total mil allocation: existing %d ; new: %d"%(totocSysThreat, totCurAlloc, ocSysAlloc ) print "-----------------" #================================ #--------Top Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = topTargetSystems print "Top Colony and Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if 2*thrt>curAlloc and (curAlloc>0 or remainingMilRating > (10+ (2*thrt-curAlloc))): #only record more allocation for this invasion if we already started or have enough rating available thisAlloc =int(10.99999 + (1.5*thrt-curAlloc)) takeAny= curAlloc>0 allocations.append( (sid, thisAlloc, takeAny ,4) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Top Colony and Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" #================================ #--------Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = [sysID for sysID in AIstate.invasionTargetedSystemIDs if sysID not in topTargetSystems] print "Other Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, max(10, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if thrt>curAlloc and remainingMilRating > 10+ 1.5*(thrt-curAlloc) : #only record an allocation for this invasion if we have enough rating available thisAlloc =int(10.99999 + (thrt-curAlloc)*1.5) allocations.append( (sid, thisAlloc, False, 3) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [sysID for sysID in list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs)) if sysID not in topTargetSystems] print "Other Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(threatBias +foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 1.5*(thrt-curAlloc): thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 2.0) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [] fleetSuppliableSystemIDs = empire.fleetSupplyableSystemIDs for sysID in AIstate.opponentSystemIDs: if sysID in fleetSuppliableSystemIDs: otherTargetedSystemIDs.append(sysID) else: for nID in universe.getImmediateNeighbors(sysID, empireID): if nID in fleetSuppliableSystemIDs: otherTargetedSystemIDs.append(sysID) break print "Blockade Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 1.5*(thrt-curAlloc): thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 10) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Blockade Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Blockade Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" currentMilSystems = [sid for sid, alloc, takeAny, mm in allocations ] interiorIDs = list( foAI.foAIstate.expInteriorSystemIDs) interiorTargets1 = [sid for sid in interiorIDs if ( ( sid not in currentMilSystems )) ] interiorTargets = [sid for sid in interiorIDs if ( (threatBias + foAI.foAIstate.systemStatus.get(sid, {}).get('fleetThreat', 0) >0.8*alreadyAssignedRating[sid] ) ) ] print "" print "Other Empire-Interior Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in interiorTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(interiorTargets) >0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)) ) for oSID in interiorTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0 : thisAlloc = min( min( int(0.99999 +( thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, True, 1.2) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Other interior system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Interior Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" else: print "-----------------" print "No Other Interior Systems with fleet threat " print "-----------------" monsterDens=[] exploTargetIDs, _ = ExplorationAI.getCurrentExplorationInfo(verbose=False) print "" print "Exploration-targeted Systems: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in exploTargetIDs ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(exploTargetIDs) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in exploTargetIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) if availMilRating <1125: maxMilRating = availMilRating else: maxMilRating = 0.5*availMilRating for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: if foAI.foAIstate.systemStatus.get(sid, {}).get('monsterThreat', 0) > 2000: monsterDens.append(sid) continue # consider dealing with big monsters later thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 2) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Exploration-targeted %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Exploration-targeted s under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] currentMilSystems = [sid for sid, alloc, takeAny, multiplier in allocations if alloc > 0 ] borderTargets1 = [sid for sid in accessibleSystemIDs if ( ( sid not in currentMilSystems )) ] borderTargets = [sid for sid in borderTargets1 if ( ( threatBias +foAI.foAIstate.systemStatus.get(sid, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(sid, {}).get('planetThreat', 0) > 0.8*alreadyAssignedRating[sid] )) ] print "" print "Empire-Accessible Systems not yet allocated military: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID) and universe.getSystem(sysID).name) for sysID in borderTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(borderTargets) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) for oSID in borderTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: if foAI.foAIstate.systemStatus.get(sid, {}).get('monsterThreat', 0) > 2000: if sid not in monsterDens: monsterDens.append(sid) continue # consider dealing with big monsters later thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 5) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Other Empire-Accessible system %4d ( %10s ) has local biased threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Empire-Accessible Systems under total biased threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" else: print "-----------------" print "No Other Empire-Accessible Systems with biased local threat " print "-----------------" print "" print "Big-Monster Dens: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in monsterDens ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(monsterDens) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) ) ) for oSID in monsterDens ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 2* thrt: thisAlloc = int(0.99999 + (thrt-curAlloc)*1.5) allocations.append( (sid, thisAlloc, False, 5) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Monster Den %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" if remainingMilRating <=6: newAllocations = [ (sid, alc, alc, ta) for (sid, alc, ta, mm) in allocations ] else: try: totAlloc = sum( [alloc for sid, alloc, takeAny, maxMul in allocations ] ) except: print "error unpacking sid, alloc, takeAny, maxMul from ", allocations factor =(2.0* remainingMilRating ) / ( totAlloc + 0.1) print "Remaining military strength allocation %d will be allocated as %.1f %% surplus allocation to top current priorities"%(remainingMilRating, 100*factor) newAllocations = [] for sid, alloc, takeAny, maxMul in allocations: if remainingMilRating <= 0 : newAllocations.append( ( sid, alloc, alloc, takeAny ) ) else: thisAlloc = int( max( maxMul-1, factor )* alloc ) newAllocations.append( ( sid, alloc+thisAlloc, alloc, takeAny ) ) remainingMilRating -= thisAlloc MilitaryAllocations = newAllocations minMilAllocations = dict( [ (sid, alloc) for sid, alloc, takeAny, mm in allocations ] ) print "------------------------------\nFinal Military Allocations: %s \n-----------------------"%dict( [ (sid, alloc) for sid, alloc, minalloc, takeAny in newAllocations ] ) # export military systems for other AI modules AIstate.militarySystemIDs = [sid for sid, alloc, minalloc, takeAny in newAllocations]
def generateResourcesOrders(): "generate resources focus orders" # get the highest resource priorities universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) capitalID = PlanetUtilsAI.getCapitalID() print "Resources Management:" print "" print "Resource Priorities:" resourcePriorities = {} for priorityType in getAIPriorityResourceTypes(): resourcePriorities[priorityType] = foAI.foAIstate.getPriority(priorityType) sortedPriorities = resourcePriorities.items() sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True) topPriority = -1 for evaluationPair in sortedPriorities: if topPriority < 0: topPriority = evaluationPair[0] print " ID|Score: " + str(evaluationPair) print " Top Resource Priority: " + str(topPriority) if topPriority == AIPriorityType.PRIORITY_RESOURCE_FOOD: newFocus = AIFocusType.FOCUS_FARMING print " New Resource Focus: " + str(newFocus) for planetID in ownedPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and newFocus in planet.availableFoci: print " Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus) fo.issueChangeFocusOrder(planetID, newFocus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_MINERALS: newFocus = AIFocusType.FOCUS_MINING print " Top Resource Focus: " + str(newFocus) for planetID in ownedPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and newFocus in planet.availableFoci: print " Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus) fo.issueChangeFocusOrder(planetID, newFocus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION: newFocus = AIFocusType.FOCUS_INDUSTRY print " New Resource Focus: " + str(newFocus) for planetID in ownedPlanetIDs: planet = universe.getPlanet(planetID) focus = newFocus if planetID == capitalID and newFocus in planet.availableFoci: print " Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus) fo.issueChangeFocusOrder(planetID, newFocus) elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH: newFocus = AIFocusType.FOCUS_RESEARCH print " New Resource Focus: " + str(newFocus) # what is the focus of available resource centers? print "" print "Planet Resources Foci:" print "" print " Empire Owned planetIDs:" + str(ownedPlanetIDs) for planetID in ownedPlanetIDs: planet = universe.getPlanet(planetID) planetPopulation = planet.currentMeterValue(fo.meterType.population) print " ID: " + str(planetID) + " Name: " + str(planet.name) + " Type: " + str(planet.type) + " Size: " + str(planet.size) + " Focus: " + str(planet.focus) + " Species: " + str(planet.speciesName) + " Population: " + str(planetPopulation)
def setGeneralPlanetResourceFocus(): "set resource focus of planets except capitalID, asteroids, and gas giants" global __timerFile universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID timer= [ time() ] # getPlanets empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) timer.append( time() ) #filter capitalIDL = [PlanetUtilsAI.getCapital()] asteroids = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.asteroids) gasGiants = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.gasGiant) generalPlanetIDs = list(set(empirePlanetIDs) - (set(capitalIDL)|set(asteroids)|set(gasGiants))) timer.append( time() ) #Priority #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION) rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH) priorityRatio = float(ppPrio)/(rpPrio+0.0001) timer.append( time() ) # shuffle # not supporting Growth for general planets until also adding code to make sure would actually benefit shuffle(generalPlanetIDs) timer.append( time() ) # targets pp, rp = getResourceTargetTotals() targetRatio = pp/(rp+0.0001) nplanets = len(generalPlanetIDs) nChanges = int( ( nplanets * max( 1.0/(rp+0.001), 2.0/(pp+0.0001)) * ( (pp - rp* priorityRatio)/(priorityRatio +2))) +0.5 ) # weird formula I came up with to estimate desired number of changes print "current target totals -- pp: %.1f rp: %.1f ; ratio %.2f ; desired ratio %.2f will change up to %d foci from total of %d planets"%(pp, rp, targetRatio, priorityRatio, nChanges, nplanets) timer.append( time() ) #loop iChanges = 0 for planetID in generalPlanetIDs: if iChanges >= nChanges: break planet = universe.getPlanet(planetID) oldFocus=planet.focus targetRatio = pp/(rp + 0.0001) ratioRatio = priorityRatio / ( targetRatio + 0.0001) if (AIFocusType.FOCUS_MINING in planet.availableFoci): #and ((priorityRatio > 0.5 ) or ( ratioRatio > 0.9 ) ) : #could be a more complex decision here, if oldFocus != AIFocusType.FOCUS_MINING: iChanges +=1 #even if not necessarily directed towards desired ratio fo.issueChangeFocusOrder(planetID, AIFocusType.FOCUS_MINING) print "Changing planet focus for ID %s : %s from %s to %s "%(planetID, planet.name, oldFocus, AIFocusType.FOCUS_MINING ) continue newFocus=None if ( ratioRatio > 1.1 ): #needs industry if oldFocus == AIFocusType.FOCUS_INDUSTRY: continue else: newFocus = AIFocusType.FOCUS_INDUSTRY elif ( ratioRatio < 0.91 ): if oldFocus == AIFocusType.FOCUS_RESEARCH: continue else: newFocus = AIFocusType.FOCUS_RESEARCH if newFocus: #pp -= planet.currentMeterValue(fo.meterType.targetIndustry) #rp -= planet.currentMeterValue(fo.meterType.targetResearch) fo.issueChangeFocusOrder(planetID, newFocus) iChanges += 1 #pp += planet.currentMeterValue(fo.meterType.targetIndustry) #rp += planet.currentMeterValue(fo.meterType.targetResearch) print "Changing planet focus for ID %s : %s from %s to %s "%(planetID, planet.name, oldFocus, newFocus ) timer.append( time() ) #end if doResourceTiming and __timerEntries==__timerEntries2: times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] timeFmt = "%30s: %8d msec " print "ResourcesAI Time Requirements:" for mod, modTime in zip(__timerEntries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if resourceTimerFile: print "len times: %d ; len entries: %d "%(len(times), len(__timerEntries)) resourceTimerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') resourceTimerFile.flush()
def getColonyFleets(): global empireSpecies, empireColonizers, empireSpeciesSystems, annexableSystemIDs, annexableRing1, annexableRing2, annexableRing3 global annexablePlanetIDs, curBestMilShipRating curBestMilShipRating = ProductionAI.curBestMilShipRating() "get colony fleets" allColonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION) AIstate.colonyFleetIDs[:] = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allColonyFleetIDs) # get suppliable systems and planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() #capitalID = empire.capitalID homeworld=None if capitalID: homeworld = universe.getPlanet(capitalID) if homeworld: speciesName = homeworld.speciesName homeworldName=homeworld.name homeSystemID = homeworld.systemID else: speciesName = "" homeworldName=" no remaining homeworld " homeSystemID = -1 if not speciesName: speciesName = foAI.foAIstate.origSpeciesName species = fo.getSpecies(speciesName) if not species: print "**************************************************************************************" print "**************************************************************************************" print "Problem determining species for colonization planning: capitalID: %s, homeworld %s and species name %s"%(capitalID, homeworldName, speciesName) else: print "Plannning colonization for species name %s"%species.name fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) print "" print " fleetSupplyableSystemIDs: " + str(list(fleetSupplyableSystemIDs)) print " fleetSupplyablePlanetIDs: " + str(fleetSupplyablePlanetIDs) print "" print "-------\nEmpire Obstructed Starlanes:" print list(empire.obstructedStarlanes()) annexableSystemIDs.clear() annexableRing1.clear() annexableRing2.clear() annexableRing3.clear() annexablePlanetIDs.clear() for sysID in empire.fleetSupplyableSystemIDs: annexableSystemIDs.add(sysID) for nID in universe.getImmediateNeighbors(sysID, empireID): annexableSystemIDs.add(nID) annexableRing1.add(nID) annexableRing1.difference_update(empire.fleetSupplyableSystemIDs) print "First Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing1) if empire.getTechStatus("CON_ORBITAL_CON") == fo.techStatus.complete: for sysID in list(annexableRing1): for nID in universe.getImmediateNeighbors(sysID, empireID): annexableRing2.add(nID) annexableRing2.difference_update(annexableSystemIDs) print "Second Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing2) annexableSystemIDs.update(annexableRing2) if foAI.foAIstate.aggression > fo.aggression.cautious: for sysID in list(annexableRing2): for nID in universe.getImmediateNeighbors(sysID, empireID): annexableRing3.add(nID) annexableRing3.difference_update(annexableSystemIDs) print "Third Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing3) annexableSystemIDs.update(annexableRing3) annexablePlanetIDs.update( PlanetUtilsAI.getPlanetsInSystemsIDs(annexableSystemIDs)) # get outpost and colonization planets exploredSystemIDs = foAI.foAIstate.getExplorableSystems(AIExplorableSystemType.EXPLORABLE_SYSTEM_EXPLORED) unExSysIDs = list(foAI.foAIstate.getExplorableSystems(AIExplorableSystemType.EXPLORABLE_SYSTEM_UNEXPLORED)) unExSystems = map(universe.getSystem, unExSysIDs) print "Unexplored Systems: %s " % [(sysID, (sys and sys.name) or "name unknown") for sysID, sys in zip( unExSysIDs, unExSystems)] print "Explored SystemIDs: " + str(list(exploredSystemIDs)) exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) print "Explored PlanetIDs: " + str(exploredPlanetIDs) print "" #visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() #visiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(visibleSystemIDs) #print "VisiblePlanets: %s "%[ (pid, (universe.getPlanet(pid) and universe.getPlanet(pid).name) or "unknown") for pid in visiblePlanetIDs] #print "" #accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] #acessiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(accessibleSystemIDs) empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) print "Empire Owned PlanetIDs: " + str(empireOwnedPlanetIDs) #allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) #working with Explored systems not all 'visible' because might not have a path to the latter allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(annexablePlanetIDs) # print "All annexable Owned or Populated PlanetIDs: " + str(set(allOwnedPlanetIDs)-set(empireOwnedPlanetIDs)) #unOwnedPlanetIDs = list(set(exploredPlanetIDs) -set(allOwnedPlanetIDs)) unOwnedPlanetIDs = list(set(annexablePlanetIDs) -set(allOwnedPlanetIDs)) print "UnOwned annexable PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(unOwnedPlanetIDs)) empirePopCtrs = set( PlanetUtilsAI.getPopulatedPlanetIDs( empireOwnedPlanetIDs) ) empireOutpostIDs=set(empireOwnedPlanetIDs) - empirePopCtrs AIstate.popCtrIDs[:]=list(empirePopCtrs) AIstate.popCtrSystemIDs[:]=list(set(PlanetUtilsAI.getSystems(empirePopCtrs))) AIstate.outpostIDs[:]=list(empireOutpostIDs) AIstate.outpostSystemIDs[:]=list(set(PlanetUtilsAI.getSystems(empireOutpostIDs))) AIstate.colonizedSystems.clear() for pid in empireOwnedPlanetIDs: planet=universe.getPlanet(pid) if planet: AIstate.colonizedSystems.setdefault(planet.systemID, []).append(pid) # track these to plan Solar Generators and Singularity Generators AIstate.empireStars.clear() for sysID in AIstate.colonizedSystems: system = universe.getSystem(sysID) if system: AIstate.empireStars.setdefault(system.starType, []).append(sysID) oldPopCtrs=[] for specN in empireSpecies: oldPopCtrs.extend(empireSpecies[specN]) oldEmpSpec = empireSpecies empireSpecies.clear() oldEmpCol=empireColonizers empireColonizers.clear() if empire.getTechStatus(TechsListsAI.exobotTechName) == fo.techStatus.complete: empireColonizers["SP_EXOBOT"]=[]# get it into colonizer list even if no colony yet empireSpeciesSystems.clear() for pID in empirePopCtrs: planet=universe.getPlanet(pID) if not planet: print "Error empire has apparently lost sight of former colony at planet %d but doesn't realize it"%pID continue pSpecName=planet.speciesName if pID not in oldPopCtrs: if (AIFocusType.FOCUS_MINING in planet.availableFoci): fo.issueChangeFocusOrder(pID, AIFocusType.FOCUS_MINING) print "Changing focus of newly settled planet ID %d : %s to mining "%(pID, planet.name ) empireSpecies[pSpecName] = empireSpecies.get(pSpecName, [])+[pID] print "\n"+"Empire species roster:" for specName in empireSpecies: thisSpec=fo.getSpecies(specName) if thisSpec: shipyards=[] for pID in empireSpecies[specName]: planet=universe.getPlanet(pID) if thisSpec.canColonize: if "BLD_SHIPYARD_BASE" in [universe.getObject(bldg).buildingTypeName for bldg in planet.buildingIDs]: shipyards.append(pID) empireSpeciesSystems.setdefault(planet.systemID, {}).setdefault('pids', []).append(pID) if thisSpec.canColonize: empireColonizers[specName]=shipyards print "%s on planets %s; can%s colonize from %d shipyards; has tags %s"%(specName, empireSpecies[specName], ["not", ""][thisSpec.canColonize], len(shipyards), list(thisSpec.tags)) else: print "Unable to retrieve info for Species named %s"%specName print"" if empireSpecies!=oldEmpSpec: print "Old empire species: %s ; new empire species: %s"%(oldEmpSpec, empireSpecies) if empireColonizers!=oldEmpCol: print "Old empire colonizers: %s ; new empire colonizers: %s"%(oldEmpCol, empireColonizers) print # export colony targeted systems for other AI modules colonyTargetedPlanetIDs = getColonyTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, empireID) allColonyTargetedSystemIDs = PlanetUtilsAI.getSystems(colonyTargetedPlanetIDs) AIstate.colonyTargetedSystemIDs = allColonyTargetedSystemIDs print "" print "Colony Targeted SystemIDs: " + str(AIstate.colonyTargetedSystemIDs) print "Colony Targeted PlanetIDs: " + str(colonyTargetedPlanetIDs) colonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION) if not colonyFleetIDs: print "Available Colony Fleets: 0" else: print "Colony FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION)) numColonyFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(colonyFleetIDs)) print "Colony Fleets Without Missions: " + str(numColonyFleets) outpostTargetedPlanetIDs = getOutpostTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_OUTPOST, empireID) allOutpostTargetedSystemIDs = PlanetUtilsAI.getSystems(outpostTargetedPlanetIDs) # export outpost targeted systems for other AI modules AIstate.outpostTargetedSystemIDs = allOutpostTargetedSystemIDs print "" print "Outpost Targeted SystemIDs: " + str(AIstate.outpostTargetedSystemIDs) print "Outpost Targeted PlanetIDs: " + str(outpostTargetedPlanetIDs) outpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST) if not outpostFleetIDs: print "Available Outpost Fleets: 0" else: print "Outpost FleetIDs: " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST)) numOutpostFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(outpostFleetIDs)) print "Outpost Fleets Without Missions: " + str(numOutpostFleets) evaluatedColonyPlanetIDs = list(set(unOwnedPlanetIDs).union(empireOutpostIDs) - set(colonyTargetedPlanetIDs) ) # print "Evaluated Colony PlanetIDs: " + str(evaluatedColonyPlanetIDs) evaluatedOutpostPlanetIDs = list(set(unOwnedPlanetIDs) - set(outpostTargetedPlanetIDs)- set(colonyTargetedPlanetIDs)) # print "Evaluated Outpost PlanetIDs: " + str(evaluatedOutpostPlanetIDs) evaluatedColonyPlanets = assignColonisationValues(evaluatedColonyPlanetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, fleetSupplyablePlanetIDs, species, empire) removeLowValuePlanets(evaluatedColonyPlanets) sortedPlanets = evaluatedColonyPlanets.items() sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "" print "Settleable Colony Planets (score,species) | ID | Name | Specials:" for ID, score in sortedPlanets: print " %15s | %5s | %s | %s "%(score, ID, universe.getPlanet(ID).name , list(universe.getPlanet(ID).specials)) print "" # export planets for other AI modules foAI.foAIstate.colonisablePlanetIDs = sortedPlanets#TODO: should include species designation corresponding to rating # get outpost fleets allOutpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST) AIstate.outpostFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allOutpostFleetIDs) evaluatedOutpostPlanets = assignColonisationValues(evaluatedOutpostPlanetIDs, AIFleetMissionType.FLEET_MISSION_OUTPOST, fleetSupplyablePlanetIDs, species, empire) removeLowValuePlanets(evaluatedOutpostPlanets) #bad! lol, was preventing all mining outposts sortedOutposts = evaluatedOutpostPlanets.items() sortedOutposts.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "Settleable Outpost PlanetIDs:" for ID, score in sortedOutposts: print " %5s | %5s | %s | %s "%(score, ID, universe.getPlanet(ID).name , list(universe.getPlanet(ID).specials)) print "" # export outposts for other AI modules foAI.foAIstate.colonisableOutpostIDs = sortedOutposts
def getMilitaryFleets(): "get armed military fleets" allMilitaryFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY) AIstate.militaryFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allMilitaryFleetIDs) # get systems to defend universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = empire.capitalID capitalPlanet = universe.getPlanet(capitalID) capitalPlanetSystem = capitalPlanet.systemID capitalSystemID = [] capitalSystemID.append(capitalPlanetSystem) fleetSupplyableSystemIDs = list(empire.fleetSupplyableSystemIDs) exploredSystemIDs = empire.exploredSystemIDs # print "Explored SystemIDs: " + str(list(exploredSystemIDs)) exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs) allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) allPopulatedSystemIDs = PlanetUtilsAI.getAllPopulatedSystemIDs(allOwnedPlanetIDs) print "" print "All Populated SystemIDs: " + str(list(set(allPopulatedSystemIDs))) empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) empireOccupiedSystemIDs = list(set(PlanetUtilsAI.getSystemsOccupiedByEmpire(empirePlanetIDs, empireID))) print "" print "Empire Capital SystemID: " + str(capitalSystemID) # print "Empire Occupied SystemIDs: " + str(empireOccupiedSystemIDs) empireProvinceSystemIDs = list(set(empireOccupiedSystemIDs) - set(capitalSystemID)) print "Empire Province SystemIDs: " + str(empireProvinceSystemIDs) competitorSystemIDs = list(set(allPopulatedSystemIDs) - set(empireOccupiedSystemIDs)) print "Competitor SystemIDs: " + str(competitorSystemIDs) otherTargetedSystemIDs = list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + AIstate.invasionTargetedSystemIDs)) print "Other Targeted SystemIDs: " + str(otherTargetedSystemIDs) militaryTheaterSystemIDs = list(set(fleetSupplyableSystemIDs + empireOccupiedSystemIDs + competitorSystemIDs + otherTargetedSystemIDs)) print "Military Theater SystemIDs: " + str(militaryTheaterSystemIDs) allMilitaryTargetedSystemIDs = getMilitaryTargetedSystemIDs(universe.systemIDs, AIFleetMissionType.FLEET_MISSION_MILITARY, empireID) # export military targeted systems for other AI modules AIstate.militaryTargetedSystemIDs = allMilitaryTargetedSystemIDs print "" print "Military Targeted SystemIDs: " + str(allMilitaryTargetedSystemIDs) militaryFleetIDs = allMilitaryFleetIDs if not militaryFleetIDs: print "Available Military Fleets: 0" else: print "Military FleetIDs: " + str(allMilitaryFleetIDs) numMilitaryFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(militaryFleetIDs)) print "Military Fleets Without Missions: " + str(numMilitaryFleets) evaluatedSystemIDs = list(set(militaryTheaterSystemIDs) - set(allMilitaryTargetedSystemIDs)) # print "Evaluated SystemIDs: " +str(evaluatedSystemIDs) evaluatedSystems = assignMilitaryValues(evaluatedSystemIDs, AIFleetMissionType.FLEET_MISSION_MILITARY, empireProvinceSystemIDs, otherTargetedSystemIDs, empire) sortedSystems = evaluatedSystems.items() sortedSystems.sort(lambda x, y: cmp(x[1], y[1]), reverse=True) print "" print "Military SystemIDs:" for evaluationPair in sortedSystems: print " ID|Score: " + str(evaluationPair) # export military systems for other AI modules AIstate.militarySystemIDs = sortedSystems