def calculateMilitaryPriority(): "calculates the demand for military ships by military targeted systems" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: homeSystemID=-1 totalThreat = 0 for sysStatus in foAI.foAIstate.systemStatus.values(): totalThreat += max(0, (sysStatus.get('fleetThreat', 0) + sysStatus.get('planetThreat', 0) - 0.7*sysStatus.get('monsterThreat', 0) + sysStatus.get('neighborThreat', 0) )) #being safe; should never be neg since fleetThreat should include monsterThreat totalFleetRating = 0 for fleetStatus in foAI.foAIstate.fleetStatus.values(): totalFleetRating += fleetStatus.get('rating', {}).get('overall', 0) #numMilitaryTargetedSystemIDs = len(AIstate.militaryTargetedSystemIDs) #militaryShipIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY) #numMilitaryShips = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(militaryShipIDs)) curShipRating = curBestMilShipRating() if fo.currentTurn() < 20: threatBias = 0 elif fo.currentTurn() < 40: threatBias = 10 elif fo.currentTurn() < 60: threatBias = 80 elif fo.currentTurn() < 80: threatBias = 100 else: threatBias = 200 if threatBias > 0: threatBias = max(threatBias, curShipRating) visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] totalBias = len(accessibleSystemIDs) * threatBias # build one more military ship than military targeted systems #militaryPriority = 100 * ((numMilitaryTargetedSystemIDs +2) - numMilitaryShips) / (numMilitaryTargetedSystemIDs + 1) militaryPriority = int( 40 + max(0, 15*((1.25*totalThreat +threatBias - totalFleetRating ) / curShipRating)) ) print "Military Priority Calc: int( 40 + max(0, 10*((1.25*totalThreat(%d) - totalFleetRating(%d) ) / curShipRating(%d) )) ) = %d"%(totalThreat, totalFleetRating, curShipRating, militaryPriority) # print "" # print "Number of Military Ships Without Missions: " + str(numMilitaryShips) # print "Number of Military Targeted Systems: " + str(numMilitaryTargetedSystemIDs) # print "Priority for Military Ships: " + str(militaryPriority) return max( militaryPriority, 0)
def calculateMilitaryPriority(): "calculates the demand for military ships by military targeted systems" universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() if capitalID: homeworld = universe.getPlanet(capitalID) else: return 0# no capitol (not even a capitol-in-the-making), means can't produce any ships allottedInvasionTargets = 1+ int(fo.currentTurn()/25) targetPlanetIDs = [pid for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets] ] + [pid for pid, pscore in foAI.foAIstate.colonisablePlanetIDs[:allottedColonyTargets] ] + [pid for pid, pscore in foAI.foAIstate.colonisableOutpostIDs[:allottedColonyTargets] ] mySystems = set( AIstate.popCtrSystemIDs ).union( AIstate.outpostSystemIDs ) targetSystems = set( PlanetUtilsAI.getSystems(targetPlanetIDs) ) curShipRating = curBestMilShipRating() unmetThreat = 0.0 currentTurn=fo.currentTurn() for sysID in mySystems.union(targetSystems) : status=foAI.foAIstate.systemStatus.get( sysID, {} ) myAttack, myHealth =0, 0 for fid in status.get('myfleets', []) : rating= foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) myAttack += rating.get('attack', 0) myHealth += rating.get('health', 0) myRating = myAttack*myHealth baseMonsterThreat = status.get('monsterThreat', 0) if currentTurn>200: monsterThreat = baseMonsterThreat elif currentTurn>100: if baseMonsterThreat <2000: monsterThreat = baseMonsterThreat else: monsterThreat = 2000 + (currentTurn/100.0 - 1) *(baseMonsterThreat-2000) else: monsterThreat = 0 if sysID in mySystems: threat = status.get('fleetThreat', 0) + status.get('planetThreat', 0) + 0.3* status.get('neighborThreat', 0) else: threat = status.get('fleetThreat', 0) + status.get('planetThreat', 0) + 0.1* status.get('neighborThreat', 0) unmetThreat += max( 0, threat + monsterThreat - myRating ) militaryPriority = int( 40 + max(0, 75*unmetThreat / curShipRating) ) return max( militaryPriority, 0)
def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire): "return the invasion value of a planet" buildingValues = {"BLD_IMPERIAL_PALACE": 1000, "BLD_CULTURE_ARCHIVES": 1000, "BLD_SHIPYARD_BASE": 100, "BLD_SHIPYARD_ORG_ORB_INC": 200, "BLD_SHIPYARD_ORG_XENO_FAC": 200, "BLD_SHIPYARD_ORG_CELL_GRO_CHAMB": 200, "BLD_SHIPYARD_CON_NANOROBO": 300, "BLD_SHIPYARD_CON_GEOINT": 400, "BLD_SHIPYARD_CON_ADV_ENGINE": 1000, "BLD_SHIPYARD_AST": 150, "BLD_SHIPYARD_AST_REF": 500, "BLD_SHIPYARD_ENRG_COMP": 500, "BLD_SHIPYARD_ENRG_SOLAR": 1500, "BLD_INDUSTRY_CENTER": 500, "BLD_GAS_GIANT_GEN": 200, "BLD_SOL_ORB_GEN": 800, "BLD_BLACK_HOLE_POW_GEN": 2000, "BLD_ENCLAVE_VOID": 500, "BLD_NEUTRONIUM_EXTRACTOR": 2000, "BLD_NEUTRONIUM_SYNTH": 2000, "BLD_NEUTRONIUM_FORGE": 1000, "BLD_CONC_CAMP": 100, "BLD_BIOTERROR_PROJECTOR": 1000, "BLD_SHIPYARD_ENRG_COMP": 3000, } #TODO: add more factors, as used for colonization universe = fo.getUniverse() empireID = empire.empireID maxJumps=8 planet = universe.getPlanet(planetID) if (planet == None) : #TODO: exclude planets with stealth higher than empireDetection print "invasion AI couldn't get current info on planet %d"%planetID return 0, 0 bldTally=0 for bldType in [universe.getObject(bldg).buildingTypeName for bldg in planet.buildingIDs]: bldTally += buildingValues.get(bldType, 50) capitolID = PlanetUtilsAI.getCapital() if capitolID: homeworld = universe.getPlanet(capitolID) if homeworld: homeSystemID = homeworld.systemID evalSystemID = planet.systemID leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) maxJumps = leastJumpsPath troops = planet.currentMeterValue(fo.meterType.troops) maxTroops = planet.currentMeterValue(fo.meterType.maxTroops) specName=planet.speciesName species=fo.getSpecies(specName) popTSize = planet.currentMeterValue(fo.meterType.targetPopulation)#TODO: adjust for empire tech planetSpecials = list(planet.specials) pSysID = planet.systemID#TODO: check star value indVal = 0 basePopInd=0.2 prodFactor = 1 discountMultiplier=20 for special in [ "MINERALS_SPECIAL", "CRYSTALS_SPECIAL", "METALOIDS_SPECIAL"] : if special in planetSpecials: prodFactor+=1 proSingVal = [0, 4][(len( AIstate.empireStars.get(fo.starType.blackHole, [])) > 0)] indTechMap={ "GRO_ENERGY_META": 0.5, "PRO_ROBOTIC_PROD":0.4, "PRO_FUSION_GEN": 1.0, "PRO_INDUSTRY_CENTER_I": 1, "PRO_INDUSTRY_CENTER_II":1, "PRO_INDUSTRY_CENTER_III":1, "PRO_SOL_ORB_GEN": 2.0, #assumes will build a gen at a blue/white star "PRO_SINGULAR_GEN": proSingVal, } for tech in indTechMap: if (empire.getTechStatus(tech) == fo.techStatus.complete): prodFactor += indTechMap[tech] indVal = discountMultiplier * basePopInd *prodFactor*popTSize if (empire.getTechStatus("PRO_SENTIENT_AUTOMATION") == fo.techStatus.complete): indVal += discountMultiplier * 5 pmaxShield = planet.currentMeterValue(fo.meterType.maxShield) sysFThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('fleetThreat', 1000 ) sysMThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('monsterThreat', 0 ) print "invasion eval of %s %d --- maxShields %.1f -- sysFleetThreat %.1f -- sysMonsterThreat %.1f"%(planet.name, planetID, pmaxShield, sysFThrt, sysMThrt) supplyVal=0 enemyVal=0 if planet.owner!=-1 : #value in taking this away from an enemy enemyVal= 20* max(planet.currentMeterValue(fo.meterType.targetIndustry), 2*planet.currentMeterValue(fo.meterType.targetResearch)) if not species:#TODO: perhaps stealth makes planet inacccesible & should abort try: targetPop=planet.currentMeterValue(fo.meterType.targetPopulation) popVal = 2*targetPop except: popVal=0 else: popVal = evaluatePlanet(planetID, AIFleetMissionType.FLEET_MISSION_COLONISATION, [planetID], species, empire) #evaluatePlanet is imported from ColonisationAI if planetID in fleetSupplyablePlanetIDs: #TODO: extend to rings supplyVal = 100 if planet.owner== -1: #if (pmaxShield <10): if ( sysFThrt < 0.5*curBestMilShipRating() ): if ( sysMThrt < 3*curBestMilShipRating()): supplyVal = 10000 else: supplyVal = 50 planetSpecials = list(planet.specials) specialVal=0 if ( ( planet.size == fo.planetSize.asteroids ) and (empire.getTechStatus("PRO_ASTEROID_MINE") == fo.techStatus.complete ) ): specialVal= 15 #TODO: should do more eval re asteroid mining here for special in [ "MINERALS_SPECIAL", "CRYSTALS_SPECIAL", "METALOIDS_SPECIAL"] : if special in planetSpecials: specialVal +=10 # buildTime=4 return max(0, popVal+supplyVal+specialVal+bldTally+indVal+enemyVal-20*troops), min(troops+maxJumps+buildTime, maxTroops)