示例#1
0
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)
示例#2
0
def evaluateSystem(systemID, missionType, empireProvinceSystemIDs, otherTargetedSystemIDs, empire):
    "return the military value of a system"

    universe = fo.getUniverse()
    system = universe.getSystem(systemID)
    if (system == None): return 0

    # give preference to home system then closest systems
    empireID = empire.empireID
    capitalID = PlanetUtilsAI.getCapital()
    homeworld = universe.getPlanet(capitalID)
    if homeworld:
        homeSystemID = homeworld.systemID
        evalSystemID = system.systemID
        leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID))
        distanceFactor = 1.001/(leastJumpsPath + 1)
    else:
        homeSystemID=-1
        distanceFactor=0

    if systemID == homeSystemID:
        return 10
    elif systemID in empireProvinceSystemIDs:
        return 4 + distanceFactor
    elif systemID in otherTargetedSystemIDs:
        return 2 + distanceFactor
    else:
        return 1 + .25 * distanceFactor
示例#3
0
def calculateMilitaryPriority():
    "calculates the demand for military ships by military targeted systems"
    global unmetThreat

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    capitalID = PlanetUtilsAI.getCapital()
    if capitalID is not None and capitalID != -1:
        homeworld = universe.getPlanet(capitalID)
    else:
        return 0# no capitol (not even a capitol-in-the-making), means can't produce any ships
        
    have_mod_weaps = ( empire.getTechStatus("SHP_WEAPON_1_4") == fo.techStatus.complete or
                                   empire.getTechStatus("SHP_WEAPON_2_1") == fo.techStatus.complete or
                                   empire.getTechStatus("SHP_WEAPON_4_1") == fo.techStatus.complete )
        
    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 = ProductionAI.curBestMilShipRating()
    cSRR = curShipRating**0.5

    unmetThreat = 0.0
    currentTurn=fo.currentTurn()
    shipsNeeded=0
    defenses_needed = 0
    for sysID in mySystems.union(targetSystems) :
        status=foAI.foAIstate.systemStatus.get( sysID,  {} )
        myRating = status.get('myFleetRating',  0)
        my_defenses = status.get('mydefenses',  {}).get('overall', 0)
        baseMonsterThreat = status.get('monsterThreat', 0)
        #scale monster threat so that in early - mid game big monsters don't over-drive military production
        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:
            threatRoot = status.get('fleetThreat', 0)**0.5 + 0.8*status.get('max_neighbor_threat', 0)**0.5 + 0.2*status.get('neighborThreat', 0)**0.5 + monsterThreat**0.5 + status.get('planetThreat', 0)**0.5
        else:
            threatRoot = status.get('fleetThreat', 0)**0.5  + monsterThreat**0.5 + status.get('planetThreat', 0)**0.5
        shipsNeeded += math.ceil(( max(0,   (threatRoot - (myRating**0.5 + my_defenses**0.5)))**2)/curShipRating)

    #militaryPriority = int( 40 + max(0,  75*unmetThreat / curShipRating) )
    militaryPriority = int( 40 + max(0,  75*shipsNeeded) )
    if not have_mod_weaps:
        militaryPriority /= 2
    #print "Calculating Military Priority:  40 + 75 * unmetThreat/curShipRating \n\t  Priority: %d    \t unmetThreat  %.0f        curShipRating: %.0f"%(militaryPriority,  unmetThreat,  curShipRating)
    print "Calculating Military Priority:  40 + 75 * shipsNeeded \n\t  Priority: %d   \t shipsNeeded %d   \t unmetThreat  %.0f        curShipRating: %.0f"%(militaryPriority, shipsNeeded,   unmetThreat,  curShipRating)
    return max( militaryPriority,  0)
示例#4
0
def getResourceTargetTotals(empirePlanetIDs):#+
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    #empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = PlanetUtilsAI.getCapital()
    oldTargets.clear()
    oldTargets.update(newTargets)
    newTargets.clear()
    currentFocus.clear()
    currentOutput.clear()

    targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry),  planetMap.values()) )
    targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch),  planetMap.values()) )

    newFocus= IFocus
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        #canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0
        currentFocus[pid] = planet.focus
        #if  currentFocus[pid] == MFocus:
        #    mtarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry)
        currentOutput.setdefault(pid,  {} )[ IFocus] =  planet.currentMeterValue(fo.meterType.industry)
        currentOutput[pid][ RFocus] =  planet.currentMeterValue(fo.meterType.research)
        if IFocus in planet.availableFoci and planet.focus !=IFocus:
            fo.issueChangeFocusOrder(pid, IFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        itarget=planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == IFocus:
            newTargets.setdefault(pid,  {})[IFocus] = ( itarget,  rtarget )
            newTargets.setdefault(pid,  {})[GFocus] = [0,  rtarget]
        else:
            newTargets.setdefault(pid,  {})[IFocus] = ( 0, 0)
            newTargets.setdefault(pid,  {})[GFocus] = [0, 0]
        #if  currentFocus[pid] == MFocus:
        #    newTargets[pid][MFocus] = ( mtarget,  rtarget )
        if RFocus in planet.availableFoci and planet.focus!=RFocus:
            fo.issueChangeFocusOrder(pid, RFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        canFocus= planet.currentMeterValue(fo.meterType.targetPopulation) >0
        itarget=planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == RFocus:
            newTargets.setdefault(pid,  {})[RFocus] = ( itarget,  rtarget )
            newTargets[pid][GFocus][0] = itarget 
        else:
            newTargets.setdefault(pid,  {})[RFocus] = ( 0,  0 )
            newTargets[pid][GFocus][0] = 0 
        if canFocus and currentFocus[pid]  != planet.focus:
            fo.issueChangeFocusOrder(pid, currentFocus[pid]) #put it back to what it was
    universe.updateMeterEstimates(empirePlanetIDs)
    return targetPP,  targetRP
示例#5
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 = ProductionAI.curBestMilShipRating()
    cSRR = curShipRating**0.5

    unmetThreat = 0.0
    currentTurn=fo.currentTurn()
    shipsNeeded=0
    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
            
        threatRoot = status.get('fleetThreat', 0)**0.5 + status.get('planetThreat', 0)**0.5 + monsterThreat**0.5
        if sysID in mySystems:
             threatRoot +=  (0.3* status.get('neighborThreat', 0))**0.5   
        else:
             threatRoot +=  (0.1* status.get('neighborThreat', 0))**0.5   
        threat = threatRoot**2
        unmetThreat += max( 0,  threat - myRating )
        shipsNeeded += math.ceil( max(0,   (threatRoot/cSRR)- (myRating/curShipRating)**0.5 ) )
        
    #militaryPriority = int( 40 + max(0,  75*unmetThreat / curShipRating) )  
    militaryPriority = int( 40 + max(0,  75*shipsNeeded) )  
    #print "Calculating Military Priority:  40 + 75 * unmetThreat/curShipRating \n\t  Priority: %d    \t unmetThreat  %.0f        curShipRating: %.0f"%(militaryPriority,  unmetThreat,  curShipRating)
    print "Calculating Military Priority:  40 + 75 * shipsNeeded \n\t  Priority: %d   \t shipsNeeded %d   \t unmetThreat  %.0f        curShipRating: %.0f"%(militaryPriority, shipsNeeded,   unmetThreat,  curShipRating)
    return max( militaryPriority,  0)
示例#6
0
def getHomeSystemID():
    "returns the systemID of the home world"

    empire = fo.getEmpire()
    universe = fo.getUniverse()
    homeworld = universe.getPlanet(PlanetUtilsAI.getCapital())

    if homeworld:
        return homeworld.systemID

    return -1
示例#7
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()
    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)
示例#8
0
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
示例#9
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)
示例#10
0
def startNewGame(aggression=fo.aggression.aggressive): # pylint: disable=invalid-name
    "called by client at start of new game"
    global _timerFile,  _lastTurnTimestamp,  _timerBucketFile
    print "New game started, AI Agression level %d"% aggression

    # initialize AIstate
    global foAIstate
    foAIstate = AIstate.AIstate(aggression = aggression)
    foAIstate.sessionStartCleanup()
    print "Initialized foAIstate class"
    planet_id = PlanetUtilsAI.getCapital()
    planet = None
    universe = fo.getUniverse()
    if planet_id is not None and planet_id != -1:
        planet = universe.getPlanet(planet_id)
        new_name = random.choice(_capitols.get(aggression,  [""]).split('\n')).strip() + " " + planet.name
        print "Capitol City Names are: ",  _capitols
        print "This Capitol New name is ",  new_name
        res = fo.issueRenameOrder(planet_id,  new_name)
        print "Capitol Rename attempt result: %d; planet now named %s"% (res,  planet.name)
    if _timerFile:
        _timerFile.close()
    if ResourcesAI.resourceTimerFile:
        ResourcesAI.resourceTimerFile.close()
    empire_id = fo.getEmpire().empireID
    try:
        if os.path.exists("timers") and os.path.isdir("timers"):
            timerpath = "timers"+os.path.sep+"timer_%02d.dat"% (empire_id-1)
            _timerFile = open(timerpath,  'w')
            _timerFile.write("Turn\t" + "\t".join(timerEntries ) +'\n')
            timerbucketpath = "timers"+os.path.sep+"timer_bucket_%02d.dat"% (empire_id-1)
            _timerBucketFile = open(timerbucketpath,  'w')
            _timerBucketFile.write("Turn\t" + "\t".join(_timerBucketEntries) +'\n')
            _lastTurnTimestamp = time()
            if ResourcesAI.doResourceTiming:
                ResourcesAI.resourceTimerFile = open("timers"+os.path.sep+"resourceTimer_%2d.dat"%(empire_id-1),  'w')
                ResourcesAI.resourceTimerFile.write("Turn\t"+ "\t".join(ResourcesAI.timer_entries)+"\n")
            print "timer file saved at " + timerpath
    except:
        _timerFile = None
        ResourcesAI.resourceTimerFile  = None
        ResourcesAI.doResourceTiming = False
        print "Error: exception caught starting timing:  ",  traceback.format_exc()
        print "won't record timing info"
示例#11
0
def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire):
    "return the invasion value of a planet"
    #TODO: add more factors, as used for colonization
    universe = fo.getUniverse()
    empireID = empire.empireID
    distanceFactor = 0
    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
        
    capitalID = PlanetUtilsAI.getCapital()
    homeworld = universe.getPlanet(capitalID)
    if homeworld:
        homeSystemID = homeworld.systemID
        evalSystemID = planet.systemID
        leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID))
        distanceFactor = 4.0/(leastJumpsPath + 1)
        
    troops = planet.currentMeterValue(fo.meterType.troops)
    specName=planet.speciesName
    species=fo.getSpecies(specName)
    if not species:# perhaps stealth might make species info inaccessible
        targetPop=planet.currentMeterValue(fo.meterType.targetPopulation)
        if planetID in fleetSupplyablePlanetIDs:
            popVal =  4*targetPop
        else:
            popVal =  6*targetPop#assign higher value if the colony would extend our supply range
        planetSpecials = list(planet.specials)
        specialVal=0
        if  ( ( planet.size  ==  fo.planetSize.asteroids ) and  (empire.getTechStatus("PRO_ASTEROID_MINE") == fo.techStatus.complete ) ): 
                specialVal= 15   # asteroid mining is great, fast return
        for special in [ "MINERALS_SPECIAL",  "CRYSTALS_SPECIAL",  "METALOIDS_SPECIAL"] :
            if special in planetSpecials:
                specialVal = 40 
        return popVal+specialVal,  troops
    else:
        popVal = evaluatePlanet(planetID,  AIFleetMissionType.FLEET_MISSION_COLONISATION,  [planetID],  species,  empire) #evaluatePlanet is implorted from ColonisationAI
        if planetID not in fleetSupplyablePlanetIDs:
            popVal =  2.0*popVal#assign higher value if the colony would extend our supply range
        return popVal,  troops
示例#12
0
def startNewGame(aggression=fo.aggression.aggressive):
    global __timerFile,  lastTurnTimestamp,  __timerBucketFile
    print "New game started, AI Agression level %d"%aggression

    # initialize AIstate
    global foAIstate
    foAIstate = AIstate.AIstate(aggression=aggression)
    foAIstate.sessionStartCleanup()
    print "Initialized foAIstate class"
    planetID = PlanetUtilsAI.getCapital()
    planet=None
    universe=fo.getUniverse()
    if planetID is not None:
        planet = universe.getPlanet(planetID)
        fo.issueRenameOrder(planetID,  capitols.get(aggression,  "")+planet.name)
    if __timerFile:
        __timerFile.close()
    if ResourcesAI.resourceTimerFile:
        ResourcesAI.resourceTimerFile.close()
    empireID = fo.getEmpire().empireID
    try:
        if os.path.exists("timers") and os.path.isdir("timers"):
            timerpath="timers"+os.path.sep+"timer_%02d.dat"%(empireID-1)
            __timerFile = open(timerpath,  'w')
            __timerFile.write("Turn\t" + "\t".join(__timerEntries) +'\n')
            timerBucketpath="timers"+os.path.sep+"timer_bucket_%02d.dat"%(empireID-1)
            __timerBucketFile = open(timerBucketpath,  'w')
            __timerBucketFile.write("Turn\t" + "\t".join(__timerBucketEntries) +'\n')
            lastTurnTimestamp = time() 
            if ResourcesAI.doResourceTiming:
                ResourcesAI.resourceTimerFile = open("timers"+os.path.sep+"resourceTimer_%2d.dat"%(empireID-1),  'w')
                ResourcesAI.resourceTimerFile.write("Turn\t"+ "\t".join(ResourcesAI.__timerEntries)+"\n")
            print "timer file saved at "+timerpath
    except:
        __timerFile=None
        ResourcesAI.resourceTimerFile  =None
        ResourcesAI.doResourceTiming = False
        print "Error: exception caught starting timing:  ",  traceback.format_exc()
        print "won't record timing info"
示例#13
0
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

    specName=planet.speciesName
    species=fo.getSpecies(specName)
    if not species:#TODO:  probably stealth makes planet inacccesible & should abort
        return 0, 0
    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 )
    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 )  )
    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 =  max(0,  popVal+supplyVal+bldTally+enemyVal-0.8*troopCost),  plannedTroops
    print invscore, "projected Troop Cost:",  troopCost,  "planet detail ",   detail,  popVal,  supplyVal,  bldTally,  enemyVal
    return   invscore
示例#14
0
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]
示例#15
0
def evaluatePlanet(planetID, missionType, fleetSupplyablePlanetIDs, species, empire,  detail = []):
    "returns the colonisation value of a planet"
    # TODO: in planet evaluation consider specials and distance
    if detail != []:
        detail = []
    discountMultiplier = 20.0
    priorityScaling=1.0
    maxGGGs=1
    if empire.productionPoints <100:
        backupFactor = 0.0
    else:
        backupFactor = min(1.0,  (empire.productionPoints/200.0)**2 )
    
    universe = fo.getUniverse()
    claimedStars= foAI.foAIstate.misc.get('claimedStars',  {} )
    if claimedStars == {}:
        for sType in AIstate.empireStars:
            claimedStars[sType] = list( AIstate.empireStars[sType] )
        for sysID in set( AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs):
            tSys = universe.getSystem(sysID)
            if not tSys: continue
            claimedStars.setdefault( tSys.starType, []).append(sysID)
    
    empireResearchList = [element.tech for element in empire.researchQueue]
    planet = universe.getPlanet(planetID)
    if (planet == None): 
        VisMap = dictFromMap(universe.getVisibilityTurnsMap(planetID,  empire.empireID))
        print "Planet %d object not available; visMap: %s"%(planetID,  VisMap)
        return 0
    detail.append("%s : "%planet.name )
    system = universe.getSystem(planet.systemID)
    tagList=[]
    starBonus=0
    colonyStarBonus=0
    researchBonus=0
    growthVal = 0
    fixedInd = 0
    fixedRes = 0
    haveExistingPresence=False
    if  AIstate.colonizedSystems.get(planet.systemID,  [planetID]) != [planetID]: #if existing presence is target planet, don't count
        haveExistingPresence=True
    if species:
        tagList = list( species.tags )
    starPopMod=0
    if system:
        alreadyGotThisOne= planet.systemID in (AIstate.popCtrSystemIDs + AIstate.outpostSystemIDs) 
        if "PHOTOTROPHIC" in tagList:
            starPopMod = photoMap.get( system.starType,  0 )
            detail.append( "PHOTOTROPHIC popMod %.1f"%starPopMod    )
        if (empire.getTechStatus("PRO_SOL_ORB_GEN") == fo.techStatus.complete) or (  "PRO_SOL_ORB_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blue, fo.starType.white]:
                if len (claimedStars.get(fo.starType.blue,  [])+claimedStars.get(fo.starType.white,  []))==0:
                    starBonus +=20* discountMultiplier
                    detail.append( "PRO_SOL_ORB_GEN BW  %.1f"%(20* discountMultiplier)    )
                elif   not alreadyGotThisOne:
                    starBonus +=10*discountMultiplier*backupFactor #still has extra value as an alternate location for solar generators
                    detail.append( "PRO_SOL_ORB_GEN BW Backup Location  %.1f"%(10* discountMultiplier *backupFactor)   )
                elif fo.currentTurn() > 100:  #lock up this whole system
                    pass
                    #starBonus += 5 #TODO: how much?
                    #detail.append( "PRO_SOL_ORB_GEN BW LockingDownSystem   %.1f"%5  )
            if system.starType in [fo.starType.yellow, fo.starType.orange]:
                if len (     claimedStars.get(fo.starType.blue,  [])+claimedStars.get(fo.starType.white,  [])+
                                    claimedStars.get(fo.starType.yellow,  [])+claimedStars.get(fo.starType.orange,  []))==0:
                    starBonus +=10* discountMultiplier
                    detail.append( "PRO_SOL_ORB_GEN YO  %.1f"%(10* discountMultiplier ))
                else:
                    pass
                    #starBonus +=2 #still has extra value as an alternate location for solar generators
                    #detail.append( "PRO_SOL_ORB_GEN YO Backup  %.1f"%2 )
        if system.starType in [fo.starType.blackHole] and fo.currentTurn() > 100:
            if not alreadyGotThisOne:
                starBonus +=10*discountMultiplier*backupFactor #whether have tech yet or not, assign some base value
                detail.append( "Black Hole %.1f"%(10* discountMultiplier*backupFactor)    )
            else:
                starBonus += 5*discountMultiplier*backupFactor
                detail.append( "Black Hole Backup %.1f"%(5* discountMultiplier*backupFactor )   )
        if (empire.getTechStatus("PRO_SINGULAR_GEN") == fo.techStatus.complete) or (  "PRO_SINGULAR_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blackHole] :
                if len (claimedStars.get(fo.starType.blackHole,  []))==0:
                    starBonus +=200*discountMultiplier #pretty rare planets, good for generator
                    detail.append( "PRO_SINGULAR_GEN %.1f"%(200* discountMultiplier  )  )
                elif  planet.systemID not in claimedStars.get(fo.starType.blackHole,  []):
                    starBonus +=100*discountMultiplier*backupFactor #still has extra value as an alternate location for generators & for blocking enemies generators
                    detail.append( "PRO_SINGULAR_GEN Backup %.1f"%(100* discountMultiplier*backupFactor  )  )
            elif system.starType in [fo.starType.red] and ( len (claimedStars.get(fo.starType.blackHole,  [])) )==0:
                rfactor = (1.0+len (claimedStars.get(fo.starType.red,  [])))**(-2)
                starBonus +=40*discountMultiplier*backupFactor*rfactor # can be used for artificial black hole
                detail.append( "Red Star for Art Black Hole  %.1f"%(20* discountMultiplier*backupFactor*rfactor  )  )
        if (empire.getTechStatus("PRO_NEUTRONIUM_EXTRACTION") == fo.techStatus.complete) or (  "PRO_NEUTRONIUM_EXTRACTION"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.neutron]:
                if len (claimedStars.get(fo.starType.neutron,  []))==0:
                    starBonus +=80*discountMultiplier #pretty rare planets, good for armor
                    detail.append( "PRO_NEUTRONIUM_EXTRACTION  %.1f"%(80* discountMultiplier  )  )
                else:
                    starBonus +=20*discountMultiplier*backupFactor #still has extra value as an alternate location for generators & for bnlocking enemies generators
                    detail.append( "PRO_NEUTRONIUM_EXTRACTION Backup  %.1f"%(20* discountMultiplier*backupFactor  )  )
        if (empire.getTechStatus("SHP_ENRG_BOUND_MAN") == fo.techStatus.complete) or (  "SHP_ENRG_BOUND_MAN"  in empireResearchList[:6])  :    
            if system.starType in [fo.starType.blackHole,  fo.starType.blue] :
                if len (claimedStars.get(fo.starType.blackHole,  [])  +  claimedStars.get(fo.starType.blue,  []) )    ==0:
                    colonyStarBonus +=100*discountMultiplier #pretty rare planets, good for generator
                    detail.append( "SHP_ENRG_BOUND_MAN  %.1f"%(100* discountMultiplier  )  )
                elif  planet.systemID not in (claimedStars.get(fo.starType.blackHole,  [])  +  claimedStars.get(fo.starType.blue,  []) ):
                    colonyStarBonus +=50*discountMultiplier*backupFactor #still has extra value as an alternate location for generators & for bnlocking enemies generators
                    detail.append( "SHP_ENRG_BOUND_MAN Backup  %.1f"%(50* discountMultiplier*backupFactor  )  )
    retval = starBonus
    
    planetSpecials = list(planet.specials)
    if "ECCENTRIC_ORBIT_SPECIAL" in planet.specials:
        fixedRes += discountMultiplier*2*3
        detail.append( "ECCENTRIC_ORBIT_SPECIAL  %.1f"%(discountMultiplier*2*3  )  )
        
    if ( "ANCIENT_RUINS_SPECIAL" in planet.specials ): #TODO: add value for depleted ancient ruins
        retval += discountMultiplier*20
        detail.append("Undepleted Ruins %.1f"%discountMultiplier*20)
        
    if   (missionType == AIFleetMissionType.FLEET_MISSION_OUTPOST ):
        for special in planetSpecials:
            if "_NEST_" in special:
                retval+=5*discountMultiplier*backupFactor # get an outpost on the nest quick
                detail.append( "%s  %.1f"%(special,  discountMultiplier*5*backupFactor  )  )
        if  ( ( planet.size  ==  fo.planetSize.asteroids ) and  (empire.getTechStatus("PRO_MICROGRAV_MAN") == fo.techStatus.complete )): 
            if system:
                astVal=0
                for pid in system.planetIDs:
                    otherPlanet=universe.getPlanet(pid)
                    if otherPlanet.size == fo.planetSize.asteroids:
                        if pid==planetID:
                            continue
                        elif pid < planetID:
                            astVal=0
                            break
                    elif otherPlanet.size!= fo.planetSize.gasGiant and otherPlanet.owner==empire.empireID:
                        astVal+=5 * discountMultiplier
                retval += astVal
                if astVal >0:
                    detail.append( "Asteroids %.1f"%(discountMultiplier*20  )  )
        if  ( ( planet.size  ==  fo.planetSize.gasGiant ) and  ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or (  "PRO_ORBITAL_GEN"  in empireResearchList[:3]) )):
            if system:
                GGList=[]
                orbGenVal=0
                GGDetail=[]
                for pid in system.planetIDs:
                    otherPlanet=universe.getPlanet(pid)
                    if otherPlanet.size== fo.planetSize.gasGiant:
                        GGList.append(pid)
                    if  pid!=planetID and otherPlanet.owner==empire.empireID and (AIFocusType.FOCUS_INDUSTRY  in list(otherPlanet.availableFoci)+[otherPlanet.focus]):
                        orbGenVal+=2*10*discountMultiplier
                        GGDetail.append( "GGG  for %s  %.1f"%(otherPlanet.name,    discountMultiplier*10  )  )
                if planetID in sorted(GGList)[:maxGGGs]:
                    retval += orbGenVal
                    detail.extend( GGDetail )
                else:
                    detail.append( "Won't GGG")
        thrtFactor = 1.0
        if ( foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0)  + foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('monsterThreat', 0) )> 2*curBestMilShipRating:
            thrtFactor = 0.5
            retval *=thrtFactor
            detail.append( "threat reducing value" )
        if haveExistingPresence:
            detail.append("multiplanet presence")
            if thrtFactor < 1.0:
                retval = (retval/thrtFactor) * (0.5 + 0.5*thrtFactor) #mitigate threat
            retval *=1.5
        return int(retval)
    else: #colonization mission
        if not species:
            return 0
        retval += fixedRes
        retval += colonyStarBonus
        asteroidBonus=0
        gasGiantBonus=0
        GGPresent=False
        miningBonus=0
        perGGG=2*10*discountMultiplier
        planetSize = planet.size
        if system and AIFocusType.FOCUS_INDUSTRY in species.foci:
            for pid  in [id for id in system.planetIDs if id != planetID]:
                p2 = universe.getPlanet(pid)
                if p2:
                    if p2.size== fo.planetSize.asteroids :
                        if ( (empire.getTechStatus("PRO_MICROGRAV_MAN") == fo.techStatus.complete ) or (  "PRO_MICROGRAV_MAN"  in empireResearchList[:3]) ):
                            asteroidBonus = 2*5*discountMultiplier
                            detail.append( "Asteroid mining from %s  %.1f"%(p2.name,    2*discountMultiplier*5  )  )
                    if p2.size== fo.planetSize.gasGiant :
                        GGPresent=True
                        if ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or (  "PRO_ORBITAL_GEN"  in empireResearchList[:3]) ):
                            gasGiantBonus += perGGG
                            detail.append( "GGG  from %s  %.1f"%(p2.name,    perGGG  )  )
        gasGiantBonus = min( gasGiantBonus,  maxGGGs * perGGG )
        if   (planet.size==fo.planetSize.gasGiant):
            if not (species and species.name  ==  "SP_SUPER_TEST"): 
                detail.append("Can't Settle GG" )
                return 0
            else:
                planetEnv = fo.planetEnvironment.adequate#I think
                planetSize=6 #I think
        elif ( planet.size  ==  fo.planetSize.asteroids ):
            planetSize=3 #I think
            if  not species or (species.name not in [  "SP_EXOBOT", "SP_SUPER_TEST"  ]):
                detail.append( "Can't settle Asteroids" )
                return 0
            elif species.name == "SP_EXOBOT":
                planetEnv =fo.planetEnvironment.poor
            elif species.name == "SP_SUPER_TEST":
                planetEnv = fo.planetEnvironment.adequate#I think
            else:
                return 0
        else:
            planetEnv  = environs[ str(species.getPlanetEnvironment(planet.type)) ]
        if planetEnv==0:
            return -9999
        popSizeMod=0
        conditionalPopSizeMod=0
        popSizeMod += popSizeModMap["env"][planetEnv]
        detail.append("EnvironPopSizeMod(%d)"%popSizeMod)
        if "SELF_SUSTAINING" in tagList:
            popSizeMod*=2
            detail.append("SelfSustaining_PSM(2)" )
        if "PHOTOTROPHIC" in tagList:
            popSizeMod += starPopMod
            detail.append("Phototropic Star Bonus_PSM(%0.1f)"%starPopMod)
        if (empire.getTechStatus("GRO_SUBTER_HAB") == fo.techStatus.complete)  or "TUNNELS_SPECIAL" in planetSpecials:    
            if "TECTONIC_INSTABILITY_SPECIAL" not in planetSpecials:
                conditionalPopSizeMod += popSizeModMap["subHab"][planetEnv]
                if "TUNNELS_SPECIAL" in planetSpecials:
                    T_reason="Tunnels_PSM(%d)"
                else:
                    T_reason="Sub_Hab_PSM(%d)"
                detail.append(T_reason%popSizeModMap["subHab"][planetEnv])
        for gTech,  gKey in [ ("GRO_SYMBIOTIC_BIO", "symBio"), 
                                                        ("GRO_XENO_GENETICS", "xenoGen"), 
                                                        ("GRO_XENO_HYBRID", "xenoHyb"), 
                                                        ("GRO_CYBORG", "cyborg"), 
                                                        ("CON_NDIM_STRUC", "ndim"), 
                                                        ("CON_ORBITAL_HAB", "orbit") ]:
            if empire.getTechStatus(gTech) == fo.techStatus.complete:
                popSizeMod += popSizeModMap[gKey][planetEnv]
                detail.append("%s_PSM(%d)"%(gKey,  popSizeModMap[gKey][planetEnv]))

        if "GAIA_SPECIAL" in planet.specials:
            popSizeMod += 3
            detail.append("Gaia_PSM(3)")

        for special in [ "SLOW_ROTATION_SPECIAL",  "SOLID_CORE_SPECIAL"] :
            if special in planetSpecials:
                popSizeMod -= 1
                detail.append("%s_PSM(-1)"%special)

        applicableBoosts=set([])
        for thisTag in [ tag for tag in tagList if tag in  AIDependencies.metabolims]:
            metabBoosts= AIDependencies.metabolimBoostMap.get(thisTag,  [])
            if popSizeMod > 0:
                for key in activeGrowthSpecials.keys():
                    if  ( len(activeGrowthSpecials[key])>0 ) and ( key in metabBoosts ):
                        applicableBoosts.add(key)
                        detail.append("%s boost active"%key)
            for boost in metabBoosts:
                if boost in planetSpecials:
                    applicableBoosts.add(boost)
                    detail.append("%s boost present"%boost)
        
        nBoosts = len(applicableBoosts)
        if nBoosts:
            popSizeMod += nBoosts
            detail.append("boosts_PSM(%d from %s)"%(nBoosts, applicableBoosts))
        if popSizeMod > 0:
            popSizeMod += conditionalPopSizeMod

        popSize = planetSize * popSizeMod
        detail.append("baseMaxPop size*psm %d * %d = %d"%(planetSize,  popSizeMod,  popSize) )

        if "DIM_RIFT_MASTER_SPECIAL" in planet.specials:
            popSize -= 4
            detail.append("DIM_RIFT_MASTER_SPECIAL(maxPop-4)")
        detail.append("maxPop %.1f"%popSize)

        for special in [ "MINERALS_SPECIAL",  "CRYSTALS_SPECIAL",  "METALOIDS_SPECIAL"] : 
            if special in planetSpecials:
                miningBonus+=1
        
        proSingVal = [0, 4][(len( claimedStars.get(fo.starType.blackHole,  [])) > 0)]
        basePopInd=0.2
        indMult=1
        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):
                indMult += indTechMap[tech]
        indVal = 0
        if (empire.getTechStatus("PRO_SENTIENT_AUTOMATION") == fo.techStatus.complete):
            fixedInd += discountMultiplier * 5
        if AIFocusType.FOCUS_INDUSTRY  in species.foci:
            indVal += discountMultiplier * basePopInd * popSize*miningBonus
            indVal += discountMultiplier * basePopInd * popSize * indMult
        detail.append("indVal %.1f"%indVal)
        # used to give preference to closest worlds
        empireID = empire.empireID
        capitalID = PlanetUtilsAI.getCapital()
        homeworld = universe.getPlanet(capitalID)
        if homeworld:
            homeSystemID = homeworld.systemID
            evalSystemID = planet.systemID
            leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID))
            distanceFactor = 1.001 / (leastJumpsPath + 1)
        else:
            distanceFactor = 0

        for special in [ spec for spec in  planetSpecials if spec in AIDependencies.metabolimBoosts]:
            gbonus =  discountMultiplier  * basePopInd  * indMult * empireMetabolisms.get( AIDependencies.metabolimBoosts[special] , 0)#  due to growth applicability to other planets
            growthVal += gbonus
            detail.append( "Bonus for %s: %.1f"%(special,  gbonus))

        basePopRes = 0.2 #will also be doubling value of research, below
        if AIFocusType.FOCUS_RESEARCH in species.foci:
            researchBonus += discountMultiplier*2*basePopRes*popSize
            if ( "ANCIENT_RUINS_SPECIAL" in planet.specials )  or ( "ANCIENT_RUINS_DEPLETED_SPECIAL" in planet.specials ):
                researchBonus += discountMultiplier*2*basePopRes*popSize*5
                detail.append("Ruins Research")
            if "COMPUTRONIUM_SPECIAL" in planet.specials:
                researchBonus += discountMultiplier*2*10    #TODO: do actual calc
                detail.append("COMPUTRONIUM_SPECIAL")

        if popSize <= 0:
            detail.append("Non-positive population projection for species '%s',  so no colonization value"%(species and species.name))
            return 0

        retval  += max(indVal+asteroidBonus+gasGiantBonus,  researchBonus,  growthVal)+fixedInd + fixedRes
        if planet.systemID in annexableRing1:
            retval += 10
        elif planet.systemID in annexableRing2:
            retval += 20
        elif planet.systemID in annexableRing3:
            retval += 10
        
        retval *= priorityScaling
        thrtRatio = (foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0)+foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('monsterThreat', 0)+0.2*foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('neighborThreat', 0)) / float(curBestMilShipRating)
        if False:
            if thrtRatio > 4:
                retval = 0.3*retval 
            elif thrtRatio >= 2:
                retval = 0.7* retval
            elif thrtRatio > 0:
                retval = 0.85* retval
                
        thrtFactor = 1.0
        if thrtRatio > 1:
            detail.append("threat reducing value")
            thrtFactor = 0.85
            retval  *= thrtFactor
            
        if haveExistingPresence:
            detail.append("multiplanet presence")
            if thrtFactor < 1.0:
                retval = (retval/thrtFactor) * (0.5 + 0.5*thrtFactor) #mitigate threat
            retval *=1.5

    return retval
示例#16
0
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
示例#17
0
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
示例#18
0
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
示例#19
0
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])))
示例#20
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)
示例#21
0
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
示例#22
0
def generateOrders():
    global lastTurnTimestamp
    universe = fo.getUniverse()
    turnStartTime=time() #starting AI timer here, to be sure AI doesn't get blame for any  lags in server being able to provide the Universe object
    empire = fo.getEmpire()
    planetID = PlanetUtilsAI.getCapital()
    planet=None
    if planetID is not None:
        planet = universe.getPlanet(planetID)
    print "***************************************************************************"
    print "***************************************************************************"
    print ("Generating Orders")
    print "EmpireID:    " + str(empire.empireID) + " Name: " + empire.name+ "_"+str(empire.empireID-1) +"_pid:"+str(fo.playerID())+"_"+fo.playerName()+"_"+aggressions.get(foAIstate.aggression,  "?") + " Turn: " + str(fo.currentTurn())
    empireColor=empire.colour
    print "EmpireColors: %d %d %d %d"%(empireColor.r,  empireColor.g,  empireColor.b,  empireColor.a)
    if planet: 
        print "CapitalID: " + str(planetID) + " Name: " + planet.name + " Species: " + planet.speciesName 
    else:
        print "CapitalID: None Currently      Name: None     Species: None "
    print "***************************************************************************"
    print "***************************************************************************"
    
    if fo.currentTurn() == 1:
        declareWarOnAll()

    # turn cleanup !!! this was formerly done at start of every turn -- not sure why
    splitNewFleets()

    #updateShipDesigns()   #should not be needed anymore;
    #updateFleetsRoles()
    
    foAIstate.clean() #checks exploration border & clears roles/missions of missing fleets & updates fleet locs
    foAIstate.reportSystemThreats()
    # ...missions
    # ...demands/priorities

    print("Calling AI Modules")

    # call AI modules
    timer=[time()]
    try: PriorityAI.calculatePriorities()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc() # try traceback.print_exc()
    timer.append( time()  )
    try: ExplorationAI.assignScoutsToExploreSystems()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: ColonisationAI.assignColonyFleetsToColonise()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: InvasionAI.assignInvasionFleetsToInvade()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: MilitaryAI.assignMilitaryFleetsToSystems()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: ResearchAI.generateResearchOrders()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: ProductionAI.generateProductionOrders()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: ResourcesAI.generateResourcesOrders()    
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    try: foAIstate.afterTurnCleanup()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
    timer.append( time()  )
    times = [timer[i] - timer[i-1] for i in range(1,  len(timer) ) ]
    turnEndTime=time()
    timeFmt = "%30s: %8d msec  "
    print "AI Module Time Requirements:"
    for mod,  modTime in zip(__timerEntries,  times):
        print timeFmt%((30*' '+mod)[-30:],  int(1000*modTime))
    if __timerFile:
        __timerFile.write(  __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x),  times )) +'\n')
        __timerFile.flush()
    if __timerBucketFile:
        __timerBucketFile.write(  __timerBucketFileFmt%tuple( [ fo.currentTurn(),  (turnStartTime-lastTurnTimestamp)*1000, (turnEndTime-turnStartTime)*1000   ]) +'\n')
        __timerBucketFile.flush()
        lastTurnTimestamp = time()
        
    try: fo.doneTurn()
    except: print "Error: exception triggered and caught:  ",  traceback.format_exc()
示例#23
0
def evaluatePlanet(planetID, missionType, fleetSupplyablePlanetIDs, species, empire):
    "returns the colonisation value of a planet"
    # TODO: in planet evaluation consider specials and distance
    discountMultiplier = 20.0
    priorityScaling=1.0
    

    valMod = 0
    universe = fo.getUniverse()
    empireResearchList = [element.tech for element in empire.researchQueue]
    planet = universe.getPlanet(planetID)
    if (planet == None): return 0
    system = universe.getSystem(planet.systemID)
    tagList=[]
    starBonus=0
    colonyStarBonus=0
    if species:
        tagList = [tag for tag in species.tags]
    starPopMod=0
    if system:
        if "PHOTOTROPHIC" in tagList:
            starPopMod = photoMap.get( system.starType,  0 )
        if (empire.getTechStatus("PRO_SOL_ORB_GEN") == fo.techStatus.complete) or (  "PRO_SOL_ORB_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blue, fo.starType.white]:
                if len (AIstate.empireStars.get(fo.starType.blue,  [])+AIstate.empireStars.get(fo.starType.white,  []))==0:
                    starBonus +=20* discountMultiplier
                elif   planet.systemID not in (AIstate.popCtrSystemIDs + AIstate.outpostSystemIDs) :
                    starBonus +=1+10*discountMultiplier #still has extra value as an alternate location for solar generators
            if system.starType in [fo.starType.yellow, fo.starType.orange]:
                if len (     AIstate.empireStars.get(fo.starType.blue,  [])+AIstate.empireStars.get(fo.starType.white,  [])+
                                    AIstate.empireStars.get(fo.starType.yellow,  [])+AIstate.empireStars.get(fo.starType.orange,  []))==0:
                    starBonus +=10
                else:
                    starBonus +=2 #still has extra value as an alternate location for solar generators
        if system.starType in [fo.starType.blackHole] :
            starBonus +=50*discountMultiplier #whether have tech yet or not, assign some base value
        if (empire.getTechStatus("PRO_SINGULAR_GEN") == fo.techStatus.complete) or (  "PRO_SINGULAR_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blackHole] :
                if len (AIstate.empireStars.get(fo.starType.blackHole,  []))==0:
                    starBonus +=200*discountMultiplier #pretty rare planets, good for generator
                elif  planet.systemID not in (AIstate.popCtrSystemIDs + AIstate.outpostSystemIDs):
                    starBonus +=100*discountMultiplier #still has extra value as an alternate location for generators & for bnlocking enemies generators
            elif system.starType in [fo.starType.red] and ( len (AIstate.empireStars.get(fo.starType.blackHole,  [])) + len (AIstate.empireStars.get(fo.starType.red,  [])))==0:
                if  planet.systemID not in (AIstate.popCtrSystemIDs + AIstate.outpostSystemIDs):
                    starBonus +=40*discountMultiplier # can be used for artificial black hole
        if (empire.getTechStatus("PRO_NEUTRONIUM_EXTRACTION") == fo.techStatus.complete) or (  "PRO_NEUTRONIUM_EXTRACTION"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.neutron]:
                if len (AIstate.empireStars.get(fo.starType.neutron,  []))==0:
                    starBonus +=80*discountMultiplier #pretty rare planets, good for armor
                else:
                    starBonus +=20*discountMultiplier #still has extra value as an alternate location for generators & for bnlocking enemies generators
        if (empire.getTechStatus("SHP_ENRG_BOUND_MAN") == fo.techStatus.complete) or (  "SHP_ENRG_BOUND_MAN"  in empireResearchList[:6])  :    
            if system.starType in [fo.starType.blackHole,  fo.starType.blue] :
                if len (AIstate.empireStars.get(fo.starType.blackHole,  [])  +  AIstate.empireStars.get(fo.starType.blue,  []) )    ==0:
                    colonyStarBonus +=100*discountMultiplier #pretty rare planets, good for generator
                elif  planet.systemID not in (AIstate.popCtrSystemIDs + AIstate.outpostSystemIDs):
                    colonyStarBonus +=50*discountMultiplier #still has extra value as an alternate location for generators & for bnlocking enemies generators
    retval = starBonus
    
    planetSpecials = list(planet.specials)
    if   (missionType == AIFleetMissionType.FLEET_MISSION_OUTPOST ):
        for special in planetSpecials:
            if "_NEST_" in special:
                retval+=5*discountMultiplier # get an outpost on the nest quick
        if  ( ( planet.size  ==  fo.planetSize.asteroids ) and  (empire.getTechStatus("PRO_MICROGRAV_MAN") == fo.techStatus.complete )): 
            if system:
                astVal=0
                for pid in system.planetIDs:
                    otherPlanet=universe.getPlanet(pid)
                    if otherPlanet.size == fo.planetSize.asteroids:
                        if pid==planetID:
                            continue
                        elif pid < planetID:
                            astVal=0
                            break
                    elif otherPlanet.size!= fo.planetSize.gasGiant and otherPlanet.owner==empire.empireID:
                        astVal+=20 * discountMultiplier
                retval += astVal
        if  ( ( planet.size  ==  fo.planetSize.gasGiant ) and  ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or (  "PRO_ORBITAL_GEN"  in empireResearchList[:3]) )):
            if system:
                orbGenVal=0
                for pid in system.planetIDs:
                    otherPlanet=universe.getPlanet(pid)
                    if otherPlanet.size == fo.planetSize.asteroids and otherPlanet.owner==empire.empireID:
                        if empire.getTechStatus("PRO_EXOBOTS") == fo.techStatus.complete:
                            orbGenVal+=10*discountMultiplier
                    elif otherPlanet.size!= fo.planetSize.gasGiant and otherPlanet.owner==empire.empireID:
                        orbGenVal+=10*discountMultiplier
                retval += orbGenVal
        if ( foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0)  + foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('monsterThreat', 0) )> 2*curBestMilShipRating:
            retval = retval / 2.0
        return int(retval)
    else: #colonization mission
        retval += colonyStarBonus
        asteroidBonus=0
        gasGiantBonus=0
        miningBonus=0
        maxGGGs=8
        perGGG=9*discountMultiplier
        planetSize = planet.size
        if system:
            for pid  in [id for id in system.planetIDs if id != planetID]:
                p2 = universe.getPlanet(pid)
                if p2:
                    if p2.size== fo.planetSize.asteroids :
                        if ( (empire.getTechStatus("PRO_MICROGRAV_MAN") == fo.techStatus.complete ) or (  "PRO_MICROGRAV_MAN"  in empireResearchList[:3]) ):
                            asteroidBonus = 5*discountMultiplier
                    if p2.size== fo.planetSize.gasGiant :
                        if ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or (  "PRO_ORBITAL_GEN"  in empireResearchList[:3]) ):
                            gasGiantBonus += perGGG
        gasGiantBonus = min( gasGiantBonus,  maxGGGs * perGGG )
        if   (planet.size==fo.planetSize.gasGiant):
            if not (species and species.name  ==  "SP_SUPER_TEST"): 
                return 0
            else:
                planetEnv = fo.planetEnvironment.good#I think
                planetSize=4 #I think
        elif ( planet.size  ==  fo.planetSize.asteroids ):
            planetSize=3 #I think
            if  not species or (species.name not in [  "SP_EXOBOT", "SP_SUPER_TEST"  ]):
                return 0
            elif species.name == "SP_EXOBOT":
                planetEnv =fo.planetEnvironment.poor
            elif species.name == "SP_SUPER_TEST":
                planetEnv = fo.planetEnvironment.good#I think
            else:
                return 0
        else:
            planetEnv  = environs[ str(species.getPlanetEnvironment(planet.type)) ]
        if planetEnv==0:
            return -9999
        popSizeMod=0
        popSizeMod += popSizeModMap["env"][planetEnv]
        if "SELF_SUSTAINING" in tagList:
            popSizeMod*=2
        popSizeMod += starPopMod
        if (empire.getTechStatus("GRO_SUBTER_HAB") == fo.techStatus.complete)  or "TUNNELS_SPECIAL" in planetSpecials:    
            if "TECTONIC_INSTABILITY_SPECIAL" not in planetSpecials:
                popSizeMod += popSizeModMap["subHab"][planetEnv]
        if empire.getTechStatus("GRO_SYMBIOTIC_BIO") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["symBio"][planetEnv]
        if empire.getTechStatus("GRO_XENO_GENETICS") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["xenoGen"][planetEnv]
        if empire.getTechStatus("GRO_XENO_HYBRID") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["xenoHyb"][planetEnv]
        if empire.getTechStatus("GRO_CYBORG") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["cyborg"][planetEnv]
        if empire.getTechStatus("CON_NDIM_STRUC") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["ndim"][planetEnv]
        if empire.getTechStatus("CON_ORBITAL_HAB") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["orbit"][planetEnv]

        if "GAIA_SPECIAL" in planet.specials:
            popSizeMod += 3

        for special in [ "SLOW_ROTATION_SPECIAL",  "SOLID_CORE_SPECIAL"] :
            if special in planetSpecials:
                popSizeMod -= 1

        """
        for special, tag in [ ("PROBIOTIC_SPECIAL",  "ORGANIC"),
                                                           ("FRUIT_SPECIAL",  "ORGANIC"),
                                                           ("SPICE_SPECIAL",  "ORGANIC"),
                                                           ("MONOPOLE_SPECIAL",  "ROBOTIC"),
                                                           ("SUPERCONDUCTOR_SPECIAL",  "ROBOTIC"),
                                                           ("POSITRONIUM_SPECIAL",  "ROBOTIC"),
                                                           ("MINERALS_SPECIAL",  "LITHIC"),
                                                           ("METALOIDS_SPECIAL",  "LITHIC"),
                                                     ]:
                                                     """
        for special in [ spec for spec in AIDependencies.metabolimBoosts  if spec in planetSpecials]:
            valMod += 3*discountMultiplier  # extra bonus due to potential applicability to other planets
        for thisTag in [ tag for tag in tagList if tag in  AIDependencies.metabolims]:
            popSizeMod +=  len( (set(planetSpecials).union([key for key in activeGrowthSpecials.keys() if  len(activeGrowthSpecials[key])>0 ] )).intersection(AIDependencies.metabolimBoostMap.get(thisTag,  []) ) )
            
        popSize = planetSize * popSizeMod

        if "DIM_RIFT_MASTER_SPECIAL" in planet.specials:
            popSize -= 4

        for special in [ "MINERALS_SPECIAL",  "CRYSTALS_SPECIAL",  "METALOIDS_SPECIAL"] : 
            if special in planetSpecials:
                miningBonus+=1
        
        proSingVal = [0, 4][(len( AIstate.empireStars.get(fo.starType.blackHole,  [])) > 0)]
        basePopInd=0.2
        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, 
                                            }
                                            
        indVal = 0
        if (empire.getTechStatus("PRO_SENTIENT_AUTOMATION") == fo.techStatus.complete):
            indVal += discountMultiplier * 5
        indVal += discountMultiplier * basePopInd * popSize*miningBonus
        for tech in indTechMap:
            if (empire.getTechStatus(tech) == fo.techStatus.complete):
                indVal += discountMultiplier * basePopInd * popSize * indTechMap[tech]
        # used to give preference to closest worlds
        empireID = empire.empireID
        capitalID = PlanetUtilsAI.getCapital()
        homeworld = universe.getPlanet(capitalID)
        if homeworld:
            homeSystemID = homeworld.systemID
            evalSystemID = planet.systemID
            leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID))
            distanceFactor = 1.001 / (leastJumpsPath + 1)
        else:
            distanceFactor = 0

        retval=0.0
        if popSize<0:
            if foAI.foAIstate.aggression > fo.aggression.typical and (fo.currentTurn() >= 10):
                retval  = starBonus+asteroidBonus+gasGiantBonus
        elif popSize==0:
            if foAI.foAIstate.aggression > fo.aggression.typical and (fo.currentTurn() >= 10):
                retval  = 0.6*( starBonus+asteroidBonus+gasGiantBonus) #actually is kind of a pain if the pop goes close to zero but not actually zero
        else:
            retval  = starBonus+indVal+asteroidBonus+gasGiantBonus + valMod
            if planet.systemID in annexableRing1:
                retval += 10
            elif planet.systemID in annexableRing2:
                retval += 20
            elif planet.systemID in annexableRing3:
                retval += 10
            if (gasGiantBonus ==0):
                    if (  indVal + valMod  < 10*discountMultiplier):
                        if fo.currentTurn() < 15:
                            priorityScaling = 0
                        elif fo.currentTurn() < 50:
                            priorityScaling = 0.5
        
        retval *= priorityScaling
        thrtRatio = (foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0)+foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('monsterThreat', 0)+0.2*foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('neighborThreat', 0)) / float(curBestMilShipRating)
        if thrtRatio > 4:
            retval = 0.3*retval 
        elif thrtRatio >= 2:
            retval = 0.7* retval
        elif thrtRatio > 0:
            retval = 0.85* retval

    return retval
示例#24
0
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()
示例#25
0
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
示例#26
0
def evaluatePlanet(planetID, missionType, fleetSupplyablePlanetIDs, species, empire):
    "returns the colonisation value of a planet"
    # TODO: in planet evaluation consider specials and distance
    valMod = 0
    universe = fo.getUniverse()
    empireResearchList = [element.tech for element in empire.researchQueue]
    planet = universe.getPlanet(planetID)
    if (planet == None): return 0
    system = universe.getSystem(planet.systemID)
    tagList=[]
    starBonus=0
    if species:
        tagList = [tag for tag in species.tags]
    if system:
        if (empire.getTechStatus("PRO_SOL_ORB_GEN") == fo.techStatus.complete) or (  "PRO_SOL_ORB_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blue, fo.starType.white]:
                if len (AIstate.empireStars.get(fo.starType.blue,  [])+AIstate.empireStars.get(fo.starType.white,  []))==0:
                    starBonus +=40
                else:
                    starBonus +=5 #still has extra value as an alternate location for solar generators
            if system.starType in [fo.starType.yellow, fo.starType.orange]:
                if len (     AIstate.empireStars.get(fo.starType.blue,  [])+AIstate.empireStars.get(fo.starType.white,  [])+
                                    AIstate.empireStars.get(fo.starType.yellow,  [])+AIstate.empireStars.get(fo.starType.orange,  []))==0:
                    starBonus +=10
                else:
                    starBonus +=2 #still has extra value as an alternate location for solar generators
        if (empire.getTechStatus("PRO_SINGULAR_GEN") == fo.techStatus.complete) or (  "PRO_SINGULAR_GEN"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.blackHole]:
                if len (AIstate.empireStars.get(fo.starType.blackHole,  []))==0:
                    starBonus +=80 #pretty rare planets, good for generator
                else:
                    starBonus +=20 #still has extra value as an alternate location for generators & for bnlocking enemies generators
        if (empire.getTechStatus("PRO_NEUTRONIUM_EXTRACTION") == fo.techStatus.complete) or (  "PRO_NEUTRONIUM_EXTRACTION"  in empireResearchList[:8])  :    
            if system.starType in [fo.starType.neutron]:
                if len (AIstate.empireStars.get(fo.starType.neutron,  []))==0:
                    starBonus +=40 #pretty rare planets, good for armor
                else:
                    starBonus +=5 #still has extra value as an alternate location for generators & for bnlocking enemies generators
    retval = starBonus
    
    planetSpecials = list(planet.specials)
    if   (missionType == AIFleetMissionType.FLEET_MISSION_OUTPOST ):
        for special in planetSpecials:
            if "_NEST_" in special:
                retval+=10 # get an outpost on the nest quick
        if  ( ( planet.size  ==  fo.planetSize.asteroids ) and  (empire.getTechStatus("PRO_MICROGRAV_MAN") == fo.techStatus.complete )): 
                retval+=10*len( empireSpeciesSystems.get(planet.systemID , []))   # asteroid mining is good return #TODO: check that no preexisting asteroid outpost in system
        for special in [ "MINERALS_SPECIAL",  "CRYSTALS_SPECIAL",  "METALOIDS_SPECIAL"] :
            if special in planetSpecials:
                retval += 30 #expects we can make exobots soonish or will have other colonizers & want to claim the planet
        if  ( ( planet.size  ==  fo.planetSize.gasGiant ) and  ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or (  "PRO_ORBITAL_GEN"  in empireResearchList[:10]) )): 
                retval += 45*len( empireSpeciesSystems.get(planet.systemID , []))   # gias giant generators great, fast return
        if foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0) > 0:
            retval = retval / 2.0
        return int(retval)
    else: #colonization mission
        asteroidBonus=0
        gasGiantBonus=0
        if   (planet.size==fo.planetSize.gasGiant) and not (species and species.name  ==  "SP_SUPER_TEST"): 
            return 0   
        elif ( planet.size  ==  fo.planetSize.asteroids ):
            if  (species and species.name  in [  "SP_EXOBOT", "SP_SUPER_TEST"  ]):
                for special in [ "MINERALS_SPECIAL",  "CRYSTALS_SPECIAL",  "METALOIDS_SPECIAL"] : #even though as of time of writing only crystals can be in asteroids it seems
                    if special in planetSpecials:
                        retval+=60
                    else:
                        retval+=20
                thrtRatio = foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0) / float(ProductionAI.curBestMilShipRating())
                if thrtRatio > 4:
                    retval = 2* retval / thrtRatio
                elif thrtRatio >= 2:
                    retval = 0.6* retval
                elif thrtRatio > 0:
                    retval = 0.8* retval
                return int(retval)
            return 0
        if system:
            for pid  in [id for id in system.planetIDs if id != planetID]:
                p2 = universe.getPlanet(pid)
                if p2:
                    if p2.size== fo.planetSize.asteroids :
                        asteroidBonus = 5
                    if p2.size== fo.planetSize.gasGiant :
                        gasGiantBonus += 10
        planetEnv  = environs[ str(species.getPlanetEnvironment(planet.type)) ]
        popSizeMod=0
        popSizeMod += popSizeModMap["env"][planetEnv]
        if empire.getTechStatus("GRO_SUBTER_HAB") == fo.techStatus.complete:    
            if "TECTONIC_INSTABILITY_SPECIAL" not in planetSpecials:
                popSizeMod += popSizeModMap["subHab"][planetEnv]
        if empire.getTechStatus("GRO_SYMBIOTIC_BIO") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["symBio"][planetEnv]
        if empire.getTechStatus("GRO_XENO_GENETICS") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["xenoGen"][planetEnv]
        if empire.getTechStatus("GRO_XENO_HYBRID") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["xenoHyb"][planetEnv]
        if empire.getTechStatus("GRO_CYBORG") == fo.techStatus.complete:
            popSizeMod += popSizeModMap["cyborg"][planetEnv]

        for special in [ "SLOW_ROTATION_SPECIAL",  "SOLID_CORE_SPECIAL"] :
            if special in planetSpecials:
                popSizeMod -= 1

        #have to use these namelists since species tags don't seem available to AI currently
        #for special, namelist in [ ("PROBIOTIC_SPECIAL",  ["SP_HUMAN",  "SP_SCYLIOR",  "SP_GYISACHE",  "SP_HHHOH",  "SP_EAXAW"]),
        #                                                   ("FRUIT_SPECIAL",  ["SP_HUMAN",  "SP_SCYLIOR",  "SP_GYISACHE",  "SP_HHHOH",  "SP_EAXAW",  "SP_TRITH"]),
        #                                                   ("SPICE_SPECIAL",  ["SP_HUMAN",  "SP_SCYLIOR",  "SP_GYISACHE",  "SP_HHHOH",  "SP_EAXAW"]),
        #                                                   ("MONOPOLE_SPECIAL",  ["SP_CRAY"]),
        #                                                   ("SUPERCONDUCTOR_SPECIAL",  ["SP_CRAY"]),
        #                                                   ("POSITRONIUM_SPECIAL",  ["SP_CRAY"]),
        #                                                   ("MINERALS_SPECIAL",  ["SP_GEORGE",  "SP_EGASSEM"]),
        #                                                   ("METALOIDS_SPECIAL",  ["SP_GEORGE",  "SP_EGASSEM"]),
        #                                             ]:
        for special, tag in [ ("PROBIOTIC_SPECIAL",  "ORGANIC"),
                                                           ("FRUIT_SPECIAL",  "ORGANIC"),
                                                           ("SPICE_SPECIAL",  "ORGANIC"),
                                                           ("MONOPOLE_SPECIAL",  "ROBOTIC"),
                                                           ("SUPERCONDUCTOR_SPECIAL",  "ROBOTIC"),
                                                           ("POSITRONIUM_SPECIAL",  "ROBOTIC"),
                                                           ("MINERALS_SPECIAL",  "LITHIC"),
                                                           ("METALOIDS_SPECIAL",  "LITHIC"),
                                                     ]:
            if special in planetSpecials:
                valMod += 5  # extra bonus due to potential applicability to other planets, or to industry
                if  tag in tagList:
                    popSizeMod += 1
                #    print "planet %s had special %s that triggers pop mod for species %s"%(planet.name,  special,  species.name)
                #else:
                #    print "planet %s had special %s without pop mod for species %s"%(planet.name,  special,  species.name)
            
        if "GAIA_SPECIAL" in planet.specials:
            popSizeMod += 3

        popSize = planet.size * popSizeMod
        if empire.getTechStatus("CON_NDIM_STRUC") == fo.techStatus.complete:
            popSize += popSizeModMap["ndim"][planetEnv]
        if empire.getTechStatus("CON_ORBITAL_HAB") == fo.techStatus.complete:
            popSize += popSizeModMap["orbit"][planetEnv]

        if "DIM_RIFT_MASTER_SPECIAL" in planet.specials:
            popSize -= 4


        # give preference to closest worlds
        empireID = empire.empireID
        capitalID = PlanetUtilsAI.getCapital()
        homeworld = universe.getPlanet(capitalID)
        if homeworld:
            homeSystemID = homeworld.systemID
            evalSystemID = planet.systemID
            leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID))
            distanceFactor = 1.001 / (leastJumpsPath + 1)
        else:
            distanceFactor = 0
        
        if foAI.foAIstate.systemStatus.get(planet.systemID,  {}).get('fleetThreat', 0) > 0:
            threatFactor = 0.7
        else:
            threatFactor = 1.0
    
        if popSize<1:
            return 0
        if (planetID in fleetSupplyablePlanetIDs):
            return (retval+ popSize + distanceFactor + valMod + gasGiantBonus + asteroidBonus)*threatFactor
            #return getPlanetHospitality(planetID, species) * planet.size + distanceFactor
        else:
            return  (retval+popSize + distanceFactor  + valMod)*threatFactor