Beispiel #1
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

    fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
    fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)

    # get competitor planets
    exploredSystemIDs = empire.exploredSystemIDs
    exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs)

    allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs)
    # print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs)

    empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    # print "Empire Owned PlanetIDs:            " + str(empireOwnedPlanetIDs)

    competitorPlanetIDs = list(set(allOwnedPlanetIDs) - set(empireOwnedPlanetIDs))
    print "Competitor PlanetIDs:              " + str(competitorPlanetIDs)

    print ""
    print "Invasion Targeted SystemIDs:       " + str(AIstate.invasionTargetedSystemIDs)
    invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, empireID)
    allInvasionTargetedSystemIDs = PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs)
 
    # export invasion targeted systems for other AI modules
    AIstate.invasionTargetedSystemIDs = allInvasionTargetedSystemIDs
    print "Invasion Targeted PlanetIDs:       " + str(invasionTargetedPlanetIDs)

    invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION)
    if not invasionFleetIDs:
        print "Available Invasion Fleets:           0"
    else:
        print "Invasion FleetIDs:                 " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION))
 
    numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs))
    print "Invasion Fleets Without Missions:    " + str(numInvasionFleets)

    evaluatedPlanetIDs = list(set(competitorPlanetIDs) - set(invasionTargetedPlanetIDs))
    # print "Evaluated PlanetIDs:               " + str(evaluatedPlanetIDs)

    evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire)

    sortedPlanets = evaluatedPlanets.items()
    sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True)

    print ""
    print "Invadable planetIDs:"
    for evaluationPair in sortedPlanets:
        print "    ID|Score: " + str(evaluationPair)

    # export opponent planets for other AI modules
    AIstate.opponentPlanetIDs = sortedPlanets
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
0
def calculateMilitaryPriority():
    "calculates the demand for military ships by military targeted systems"

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    capitalID = PlanetUtilsAI.getCapital()
    if capitalID:
        homeworld = universe.getPlanet(capitalID)
    else:
        return 0# no capitol (not even a capitol-in-the-making), means can't produce any ships
    allottedInvasionTargets = 1+ int(fo.currentTurn()/25)
    targetPlanetIDs =  [pid for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets] ] + [pid for pid,  pscore in foAI.foAIstate.colonisablePlanetIDs[:allottedColonyTargets]  ] + [pid for pid,  pscore in foAI.foAIstate.colonisableOutpostIDs[:allottedColonyTargets]  ]
    
    mySystems = set( AIstate.popCtrSystemIDs ).union( AIstate.outpostSystemIDs   )
    targetSystems = set( PlanetUtilsAI.getSystems(targetPlanetIDs)  )
    
    curShipRating = curBestMilShipRating()

    unmetThreat = 0.0
    currentTurn=fo.currentTurn()
    for sysID in mySystems.union(targetSystems) :
        status=foAI.foAIstate.systemStatus.get( sysID,  {} )
        myAttack,  myHealth =0, 0
        for fid in status.get('myfleets', []) :
            rating= foAI.foAIstate.fleetStatus.get(fid,  {}).get('rating', {})
            myAttack += rating.get('attack', 0)
            myHealth += rating.get('health', 0)
        myRating = myAttack*myHealth
        baseMonsterThreat = status.get('monsterThreat', 0)
        if currentTurn>200:
            monsterThreat = baseMonsterThreat
        elif currentTurn>100:
            if baseMonsterThreat <2000:
                monsterThreat = baseMonsterThreat
            else:
                monsterThreat = 2000 + (currentTurn/100.0 - 1) *(baseMonsterThreat-2000)
        else:
            monsterThreat = 0
        if sysID in mySystems:
            threat = status.get('fleetThreat', 0) + status.get('planetThreat', 0) + 0.3* status.get('neighborThreat', 0)   
        else:
            threat = status.get('fleetThreat', 0) + status.get('planetThreat', 0) + 0.1* status.get('neighborThreat', 0)   
        unmetThreat += max( 0,  threat + monsterThreat - myRating )
        
    militaryPriority = int( 40 + max(0,  75*unmetThreat / curShipRating) )  
    return max( militaryPriority,  0)
def 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
Beispiel #6
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]
Beispiel #7
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
Beispiel #8
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])))
Beispiel #9
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
Beispiel #10
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
Beispiel #11
0
def getColonyFleets():
    "get colony fleets"

    allColonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION)
    AIstate.colonyFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allColonyFleetIDs)

    # get suppliable systems and planets
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    capitalID = empire.capitalID
    homeworld = universe.getPlanet(capitalID)
    speciesName = homeworld.speciesName
    species = fo.getSpecies(speciesName)

    fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
    fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)
    print ""
    print "    fleetSupplyableSystemIDs: " + str(list(fleetSupplyableSystemIDs))
    print "    fleetSupplyablePlanetIDs: " + str(fleetSupplyablePlanetIDs)
    print ""

    # get outpost and colonization planets
    exploredSystemIDs = empire.exploredSystemIDs
    print "Explored SystemIDs: " + str(list(exploredSystemIDs))

    exploredPlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(exploredSystemIDs)
    print "Explored PlanetIDs: " + str(exploredPlanetIDs)
    print ""

    allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs)
    print "All Owned and Populated PlanetIDs: " + str(allOwnedPlanetIDs)

    empireOwnedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    print "Empire Owned PlanetIDs:            " + str(empireOwnedPlanetIDs)

    unpopulatedPlanetIDs = list(set(exploredPlanetIDs) -set(allOwnedPlanetIDs))
    print "Unpopulated PlanetIDs:             " + str(unpopulatedPlanetIDs)

    print ""
    print "Colony Targeted SystemIDs:         " + str(AIstate.colonyTargetedSystemIDs)
    colonyTargetedPlanetIDs = getColonyTargetedPlanetIDs(universe.planetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, empireID)
    allColonyTargetedSystemIDs = PlanetUtilsAI.getSystems(colonyTargetedPlanetIDs)

    # export colony targeted systems for other AI modules
    AIstate.colonyTargetedSystemIDs = allColonyTargetedSystemIDs
    print "Colony Targeted PlanetIDs:         " + str(colonyTargetedPlanetIDs)

    colonyFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION)
    if not colonyFleetIDs:
        print "Available Colony Fleets:             0"
    else:
        print "Colony FleetIDs:                   " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_COLONISATION))

    numColonyFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(colonyFleetIDs))
    print "Colony Fleets Without Missions:      " + str(numColonyFleets)

    print ""
    print "Outpost Targeted SystemIDs:        " + str(AIstate.outpostTargetedSystemIDs)
    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 "Outpost Targeted PlanetIDs:        " + str(outpostTargetedPlanetIDs)

    outpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST)
    if not outpostFleetIDs:
        print "Available Outpost Fleets:            0"
    else:
        print "Outpost FleetIDs:                  " + str(FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST))

    numOutpostFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(outpostFleetIDs))
    print "Outpost Fleets Without Missions:     " + str(numOutpostFleets)

    evaluatedColonyPlanetIDs = list(set(unpopulatedPlanetIDs) - set(colonyTargetedPlanetIDs))
    # print "Evaluated Colony PlanetIDs:        " + str(evaluatedColonyPlanetIDs)

    evaluatedOutpostPlanetIDs = list(set(unpopulatedPlanetIDs) - set(outpostTargetedPlanetIDs))
    # print "Evaluated Outpost PlanetIDs:       " + str(evaluatedOutpostPlanetIDs)

    evaluatedColonyPlanets = assignColonisationValues(evaluatedColonyPlanetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION, fleetSupplyablePlanetIDs, species, empire)
    removeLowValuePlanets(evaluatedColonyPlanets)

    sortedPlanets = evaluatedColonyPlanets.items()
    sortedPlanets.sort(lambda x, y: cmp(x[1], y[1]), reverse=True)

    print ""
    print "Settleable Colony PlanetIDs:"
    for evaluationPair in sortedPlanets:
        print "    ID|Score: " + str(evaluationPair)
    print ""

    # export planets for other AI modules
    AIstate.colonisablePlanetIDs = sortedPlanets

    # get outpost fleets
    allOutpostFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_OUTPOST)
    AIstate.outpostFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allOutpostFleetIDs)

    evaluatedOutpostPlanets = assignColonisationValues(evaluatedOutpostPlanetIDs, AIFleetMissionType.FLEET_MISSION_OUTPOST, fleetSupplyablePlanetIDs, species, empire)
    removeLowValuePlanets(evaluatedOutpostPlanets)

    sortedOutposts = evaluatedOutpostPlanets.items()
    sortedOutposts.sort(lambda x, y: cmp(x[1], y[1]), reverse=True)

    print "Settleable Outpost PlanetIDs:"
    for evaluationPair in sortedOutposts:
        print "    ID|Score: " + str(evaluationPair)
    print ""

    # export outposts for other AI modules
    AIstate.colonisableOutpostIDs = sortedOutposts