def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire, secureAIFleetMissions, verbose=True): "return the invasion value (score, troops) of a planet" detail = [] 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": 300, "BLD_SHIPYARD_AST_REF": 1000, "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 access any info for planet id %d"%planetID return [0, 0] sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, empireID)).get(fo.visibility.partial, -9999) planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planetID, empireID)).get(fo.visibility.partial, -9999) if planetPartialVisTurn < sysPartialVisTurn: print "invasion AI couldn't get current info on planet id %d (was stealthed at last sighting)"%planetID return [0, 0] #last time we had partial vis of the system, the planet was stealthed to us #TODO: track detection strength, order new scouting when it goes up specName=planet.speciesName species=fo.getSpecies(specName) if not species: #this call iterates over this Empire's available species with which it could colonize after an invasion planetEval = ColonisationAI.assignColonisationValues([planetID], EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION, [planetID], None, empire, detail) #evaluatePlanet is imported from ColonisationAI popVal = max( 0.75*planetEval.get(planetID, [0])[0], ColonisationAI.evaluatePlanet(planetID, EnumsAI.AIFleetMissionType.FLEET_MISSION_OUTPOST, [planetID], None, empire, detail) ) else: popVal = ColonisationAI.evaluatePlanet(planetID, EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION, [planetID], specName, empire, detail) #evaluatePlanet is imported from ColonisationAI bldTally=0 for bldType in [universe.getObject(bldg).buildingTypeName for bldg in planet.buildingIDs]: bval = buildingValues.get(bldType, 50) bldTally += bval detail.append("%s: %d"%(bldType, bval)) pSysID = planet.systemID capitolID = PlanetUtilsAI.getCapital() leastJumpsPath = [] clear_path = True if capitolID: homeworld = universe.getPlanet(capitolID) if homeworld: homeSystemID = homeworld.systemID evalSystemID = planet.systemID if (homeSystemID != -1) and (evalSystemID != -1): leastJumpsPath = list(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) maxJumps = len(leastJumpsPath) system_status = foAI.foAIstate.systemStatus.get(pSysID, {}) sysFThrt = system_status.get('fleetThreat', 1000 ) sysMThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('monsterThreat', 0 ) sysPThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('planetThreat', 0 ) sysTotThrt = sysFThrt + sysMThrt + sysPThrt max_path_threat = sysFThrt mil_ship_rating = ProductionAI.curBestMilShipRating() for path_sys_id in leastJumpsPath: path_leg_status = foAI.foAIstate.systemStatus.get(path_sys_id, {}) path_leg_threat = path_leg_status.get('fleetThreat', 1000 ) + path_leg_status.get('monsterThreat', 0 ) if path_leg_threat > 0.5 * mil_ship_rating: clear_path = False if path_leg_threat > max_path_threat: max_path_threat = path_leg_threat troops = planet.currentMeterValue(fo.meterType.troops) maxTroops = planet.currentMeterValue(fo.meterType.maxTroops) this_system = universe.getSystem(pSysID) secure_targets = [pSysID] + list(this_system.planetIDs) system_secured = False for mission in secureAIFleetMissions: if system_secured: break secure_fleet_id = mission.target_id s_fleet = universe.getFleet(secure_fleet_id) if (not s_fleet) or (s_fleet.systemID != pSysID): continue for ai_target in mission.getAITargets(EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE): target_obj = ai_target.target_obj if (target_obj is not None) and target_obj.id in secure_targets: system_secured = True break pmaxShield = planet.currentMeterValue(fo.meterType.maxShield) if verbose: 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* (planet.currentMeterValue(fo.meterType.targetIndustry) + 2*planet.currentMeterValue(fo.meterType.targetResearch)) if pSysID in ColonisationAI.annexableSystemIDs: #TODO: extend to rings supplyVal = 100 elif pSysID in ColonisationAI.annexableRing1: supplyVal = 200 elif pSysID in ColonisationAI.annexableRing2: supplyVal = 300 elif pSysID in ColonisationAI.annexableRing2: supplyVal = 400 if ( max_path_threat > 0.5 * mil_ship_rating ): if ( max_path_threat < 3 * mil_ship_rating ): supplyVal *= 0.5 else: supplyVal *= 0.2 threatFactor = min(1, 0.2*MilitaryAI.totMilRating/(sysTotThrt+0.001))**2 #devalue invasions that would require too much military force buildTime=4 if system_secured: plannedTroops = troops else: plannedTroops = min(troops+maxJumps+buildTime, maxTroops) if ( empire.getTechStatus("SHP_ORG_HULL") != fo.techStatus.complete ): troopCost = math.ceil( plannedTroops/6.0) * ( 40*( 1+foAI.foAIstate.shipCount * AIDependencies.shipUpkeep ) ) else: troopCost = math.ceil( plannedTroops/6.0) * ( 20*( 1+foAI.foAIstate.shipCount * AIDependencies.shipUpkeep ) ) planet_score = threatFactor*max(0, popVal+supplyVal+bldTally+enemyVal-0.8*troopCost) if clear_path: planet_score *= 1.5 invscore = [ planet_score, plannedTroops ] print invscore, "projected Troop Cost:", troopCost, ", threatFactor: ", threatFactor, ", planet detail ", detail, "popval, supplyval, bldval, enemyval", popVal, supplyVal, bldTally, enemyVal return invscore
def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire): "return the invasion value of a planet" detail = [] 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 sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, empireID)).get(fo.visibility.partial, -9999) planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planetID, empireID)).get(fo.visibility.partial, -9999) if planetPartialVisTurn < sysPartialVisTurn: return 0, 0 #last time we had partial vis of the system, the planet was stealthed to us #TODO: track detection strength, order new scouting when it goes up specName=planet.speciesName species=fo.getSpecies(specName) if not species: #TODO: iterate over this Empire's available species with which it could colonize after and invasion planetEval = ColonisationAI.assignColonisationValues([planetID], EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION, [planetID], species, empire, detail) #evaluatePlanet is imported from ColonisationAI popVal = max( 0.5*planetEval[planetID][0], ColonisationAI.evaluatePlanet(planetID, EnumsAI.AIFleetMissionType.FLEET_MISSION_OUTPOST, [planetID], species, empire, detail) ) else: popVal = ColonisationAI.evaluatePlanet(planetID, EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION, [planetID], species, empire, detail) #evaluatePlanet is imported from ColonisationAI bldTally=0 for bldType in [universe.getObject(bldg).buildingTypeName for bldg in planet.buildingIDs]: bval = buildingValues.get(bldType, 50) bldTally += bval detail.append("%s: %d"%(bldType, bval)) 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) popTSize = planet.currentMeterValue(fo.meterType.targetPopulation)#TODO: adjust for empire tech planetSpecials = list(planet.specials) pSysID = planet.systemID#TODO: check star value pmaxShield = planet.currentMeterValue(fo.meterType.maxShield) sysFThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('fleetThreat', 1000 ) sysMThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('monsterThreat', 0 ) sysPThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('planetThreat', 0 ) sysTotThrt = sysFThrt + sysMThrt + sysPThrt 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* (planet.currentMeterValue(fo.meterType.targetIndustry) + 2*planet.currentMeterValue(fo.meterType.targetResearch)) if planetID in fleetSupplyablePlanetIDs: #TODO: extend to rings supplyVal = 100 if planet.owner== -1: #if (pmaxShield <10): if ( sysFThrt < 0.5*ProductionAI.curBestMilShipRating() ): if ( sysMThrt < 3*ProductionAI.curBestMilShipRating()): supplyVal = 50 else: supplyVal = 20 else: supplyVal *= int( min(1, ProductionAI.curBestMilShipRating() / sysFThrt ) ) threatFactor = min(1, 0.2*MilitaryAI.totMilRating/(sysTotThrt+0.001))**2 #devalue invasions that would require too much military force buildTime=4 plannedTroops = min(troops+maxJumps+buildTime, maxTroops) if ( empire.getTechStatus("SHP_ORG_HULL") != fo.techStatus.complete ): troopCost = math.ceil( plannedTroops/6.0) * ( 40*( 1+foAI.foAIstate.shipCount * AIDependencies.shipUpkeep ) ) else: troopCost = math.ceil( plannedTroops/6.0) * ( 20*( 1+foAI.foAIstate.shipCount * AIDependencies.shipUpkeep ) ) invscore = threatFactor*max(0, popVal+supplyVal+bldTally+enemyVal-0.8*troopCost), plannedTroops print invscore, "projected Troop Cost:", troopCost, ", threatFactor: ", threatFactor, ", planet detail ", detail, "popval, supplyval, bldval, enemyval", popVal, supplyVal, bldTally, enemyVal return invscore