Example #1
0
def setGasGiantsResourceFocus():
    "change resource focus of gas giants from farming to research"

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    newFocus = AIFocusType.FOCUS_RESEARCH
    for planetID in empirePlanetIDs:
        planet = universe.getPlanet(planetID)
        focus = newFocus
        if planet.type == fo.planetType.gasGiant and 'GRO_ORBIT_FARMING' in empire.availableTechs and focus in planet.availableFoci:
            fo.issueChangeFocusOrder(planetID, focus)
Example #2
0
def setAsteroidsResourceFocus():
    "change resource focus of asteroids from farming to mining"

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    newFocus = AIFocusType.FOCUS_INDUSTRY
    for planetID in empirePlanetIDs:
        planet = universe.getPlanet(planetID)
        focus = newFocus
        if planet.type == fo.planetType.asteroids and 'GRO_ORBIT_FARMING' in empire.availableTechs and focus in planet.availableFoci:
            fo.issueChangeFocusOrder(planetID, focus)
Example #3
0
    def bake_future_focus(self, pid, focus, update=True):
        """Set the focus and moves it from the raw list to the baked list of planets.

        pid -- pid
        focus -- future focus to use
        update -- If update is True then the meters of the raw planets will be updated.
                  If the planet's change of focus will have a global effect (growth,
                  production or research special), then update should be True.
        Return success or failure
        """
        info = self.raw_planet_info.get(pid)
        success = bool(info is not None and
                       (info.current_focus == focus
                        or (focus in info.planet.availableFoci
                            and fo.issueChangeFocusOrder(pid, focus))))
        if success:
            if update and info.current_focus != focus:
                universe = fo.getUniverse()
                universe.updateMeterEstimates(self.raw_planet_info.keys())
                industry_target = info.planet.currentMeterValue(fo.meterType.targetIndustry)
                research_target = info.planet.currentMeterValue(fo.meterType.targetResearch)
                info.possible_output[focus] = (industry_target, research_target)

            info.future_focus = focus
            self.baked_planet_info[pid] = self.raw_planet_info.pop(pid)
        return success
Example #4
0
    def bake_future_focus(self, pid, focus, update=True):
        """Set the focus and moves it from the raw list to the baked list of planets.

        pid -- pid
        focus -- future focus to use
        update -- If update is True then the meters of the raw planets will be updated.
                  If the planet's change of focus will have a global effect (growth,
                  production or research special), then update should be True.
        Return success or failure
        """
        pinfo = self.raw_planet_info.get(pid)
        success = bool(pinfo is not None
                       and (pinfo.current_focus == focus or
                            (focus in pinfo.planet.availableFoci
                             and fo.issueChangeFocusOrder(pid, focus))))
        if success:
            if update and pinfo.current_focus != focus:
                universe = fo.getUniverse()
                universe.updateMeterEstimates(self.raw_planet_info.keys())
                industry_target = pinfo.planet.currentMeterValue(
                    fo.meterType.targetIndustry)
                research_target = pinfo.planet.currentMeterValue(
                    fo.meterType.targetResearch)
                pinfo.possible_output[focus] = (industry_target,
                                                research_target)

            pinfo.future_focus = focus
            self.baked_planet_info[pid] = self.raw_planet_info.pop(pid)
        return success
Example #5
0
def getResourceTargetTotals(empirePlanetIDs,  planetMap):#+
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    #empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = PlanetUtilsAI.getCapital()
    oldTargets.clear()
    oldTargets.update(newTargets)
    newTargets.clear()
    currentFocus.clear()
    currentOutput.clear()
    
    targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry),  planetMap.values()) )
    targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch),  planetMap.values()) )
    
    newFocus= IFocus
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        #canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0
        currentFocus[pid] = planet.focus
        #if  currentFocus[pid] == MFocus:
        #    mtarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry)
        currentOutput.setdefault(pid,  {} )[ IFocus] =  planet.currentMeterValue(fo.meterType.industry)
        currentOutput[pid][ RFocus] =  planet.currentMeterValue(fo.meterType.research)
        if IFocus in planet.availableFoci and planet.focus !=IFocus:
            fo.issueChangeFocusOrder(pid, IFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        itarget=planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planet.currentMeterValue(fo.meterType.targetResearch)
        newTargets.setdefault(pid,  {})[IFocus] = ( itarget,  rtarget )
        #if  currentFocus[pid] == MFocus:
        #    newTargets[pid][MFocus] = ( mtarget,  rtarget )
        if RFocus in planet.availableFoci and planet.focus!=RFocus:
            fo.issueChangeFocusOrder(pid, RFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        planet=planetMap[pid]
        canFocus= planet.currentMeterValue(fo.meterType.targetPopulation) >0
        itarget=planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planet.currentMeterValue(fo.meterType.targetResearch)
        newTargets.setdefault(pid,  {})[RFocus] = ( itarget,  rtarget )
        #if canFocus and currentFocus[pid]  != planet.focus:
        #    fo.issueChangeFocusOrder(pid, currentFocus[pid]) #put it back to what it was
    #universe.updateMeterEstimates(empirePlanetIDs)
    return targetPP,  targetRP
Example #6
0
def setGeneralPlanetResourceFocus():
    "set resource focus of planets except capitalID, asteroids, and gas giants"

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = [empire.capitalID]
    asteroids = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.asteroids)
    gasGiants = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.gasGiant)
    generalPlanetIDs = list(set(empirePlanetIDs) - (set(capitalID)|set(asteroids)|set(gasGiants)))
    topPriority = topResourcePriority()
    fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
    fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)

    if topPriority == AIPriorityType.PRIORITY_RESOURCE_FOOD:
        newFocus = AIFocusType.FOCUS_FARMING
        for planetID in generalPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_MINERALS:
        newFocus = AIFocusType.FOCUS_MINING
        for planetID in generalPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION:
        newFocus = AIFocusType.FOCUS_INDUSTRY
        for planetID in generalPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH:
        newFocus = AIFocusType.FOCUS_RESEARCH
        for planetID in generalPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID in fleetSupplyablePlanetIDs and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    else:
        focus = AIFocusType.FOCUS_FARMING
        if focus in planet.availableFoci:
            fo.issueChangeFocusOrder(planetID, focus)
Example #7
0
def setCapitalIDResourceFocus():
    "set resource focus of CapitalID planet"

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = PlanetUtilsAI.getCapital()
    topPriority = topResourcePriority()

    if topPriority == AIPriorityType.PRIORITY_RESOURCE_GROWTH:
        newFocus = AIFocusType.FOCUS_GROWTH
        for planetID in empirePlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION:
        newFocus = AIFocusType.FOCUS_INDUSTRY
        for planetID in empirePlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH:
        newFocus = AIFocusType.FOCUS_RESEARCH
        for planetID in empirePlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and focus in planet.availableFoci:
                fo.issueChangeFocusOrder(planetID, focus)
Example #8
0
    def calculate_planet_infos(self, pids):
        """ Calculates for each possible focus the target output of each planet and stores it in planet info
        It excludes baked planets from consideration.
        Note: The results will not be strictly correct if any planets have global effects
        """
        # TODO this function depends on the specific rule that off-focus meter value are always the minimum value
        universe = fo.getUniverse()
        unbaked_pids = [
            pid for pid in pids if pid not in self.baked_planet_info
        ]
        planet_infos = [(pid, self.all_planet_info[pid],
                         self.all_planet_info[pid].planet)
                        for pid in unbaked_pids]
        for pid, pinfo, planet in planet_infos:
            if INDUSTRY in planet.availableFoci and planet.focus != INDUSTRY:
                fo.issueChangeFocusOrder(
                    pid, INDUSTRY)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, pinfo, planet in planet_infos:
            industry_target = planet.currentMeterValue(
                fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(
                fo.meterType.targetResearch)
            if planet.focus == INDUSTRY:
                pinfo.possible_output[INDUSTRY] = (industry_target,
                                                   research_target)
                pinfo.possible_output[GROWTH] = research_target
            else:
                pinfo.possible_output[INDUSTRY] = (0, 0)
                pinfo.possible_output[GROWTH] = 0
            if RESEARCH in planet.availableFoci and planet.focus != RESEARCH:
                fo.issueChangeFocusOrder(
                    pid, RESEARCH)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, pinfo, planet in planet_infos:
            industry_target = planet.currentMeterValue(
                fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(
                fo.meterType.targetResearch)
            if planet.focus == RESEARCH:
                pinfo.possible_output[RESEARCH] = (industry_target,
                                                   research_target)
                pinfo.possible_output[GROWTH] = (industry_target,
                                                 pinfo.possible_output[GROWTH])
            else:
                pinfo.possible_output[RESEARCH] = (0, 0)
                pinfo.possible_output[GROWTH] = (0,
                                                 pinfo.possible_output[GROWTH])
            if pinfo.planet.availableFoci and pinfo.current_focus != planet.focus:
                fo.issueChangeFocusOrder(
                    pid, pinfo.current_focus)  # put it back to what it was

        universe.updateMeterEstimates(unbaked_pids)
        # Protection focus will give the same off-focus Industry and Research targets as Growth Focus
        for pid, pinfo, planet in planet_infos:
            pinfo.possible_output[PROTECTION] = pinfo.possible_output[GROWTH]
Example #9
0
def _fill_data_dicts(planet_ids):
    universe = fo.getUniverse()
    newTargets.clear()
    currentFocus.clear()
    currentOutput.clear()
    planets = [(pid, planetMap[pid]) for pid in planet_ids]
    for pid, planet in planets:
        currentFocus[pid] = planet.focus
        currentOutput.setdefault(pid, {})[IFocus] = planet.currentMeterValue(
            fo.meterType.industry)
        currentOutput[pid][RFocus] = planet.currentMeterValue(
            fo.meterType.research)
        if IFocus in planet.availableFoci and planet.focus != IFocus:
            fo.issueChangeFocusOrder(
                pid, IFocus)  # may not be able to take, but try
    universe.updateMeterEstimates(planet_ids)
    for pid, planet in planets:
        itarget = planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget = planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == IFocus:
            newTargets.setdefault(pid, {})[IFocus] = (itarget, rtarget)
            newTargets.setdefault(pid, {})[GFocus] = [0, rtarget]
        else:
            newTargets.setdefault(pid, {})[IFocus] = (0, 0)
            newTargets.setdefault(pid, {})[GFocus] = [0, 0]
        # if currentFocus[pid] == MFocus:
        # newTargets[pid][MFocus] = (mtarget, rtarget)
        if RFocus in planet.availableFoci and planet.focus != RFocus:
            fo.issueChangeFocusOrder(
                pid, RFocus)  # may not be able to take, but try
    universe.updateMeterEstimates(planet_ids)
    for pid, planet in planets:
        can_focus = planet.currentMeterValue(fo.meterType.targetPopulation) > 0
        itarget = planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget = planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == RFocus:
            newTargets.setdefault(pid, {})[RFocus] = (itarget, rtarget)
            newTargets[pid][GFocus][0] = itarget
        else:
            newTargets.setdefault(pid, {})[RFocus] = (0, 0)
            newTargets[pid][GFocus][0] = 0
        if can_focus and currentFocus[pid] != planet.focus:
            fo.issueChangeFocusOrder(
                pid, currentFocus[pid])  # put it back to what it was
    universe.updateMeterEstimates(planet_ids)
    # Protection focus will give the same off-focus Industry and Research targets as Growth Focus
    for pid, planet in planets:
        newTargets[pid][PFocus] = newTargets[pid][GFocus]
Example #10
0
def getResourceTargetTotals():
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = PlanetUtilsAI.getCapital()
    #    planet = universe.getPlanet(planetID)
    #   if planet.currentMeterValue(fo.meterType.population) >0:
    planets = map(universe.getPlanet,  empirePlanetIDs)
    planetMap = dict(  zip( empirePlanetIDs,  planets)) 
    oldTargets.clear()
    oldTargets.update(newTargets)
    newTargets.clear()
    currentFocus.clear()
    currentOutput.clear()
    
    targetPP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetIndustry),  planets) )
    targetRP = sum( map( lambda x: x.currentMeterValue(fo.meterType.targetResearch),  planets) )
    
    newFocus= IFocus
    for pid in empirePlanetIDs:
        currentFocus[pid] = planetMap[pid].focus
        if  currentFocus[pid] == MFocus:
            mtarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry)
        currentOutput.setdefault(pid,  {} )[ IFocus] =  planetMap[pid].currentMeterValue(fo.meterType.industry)
        currentOutput[pid][ RFocus] =  planetMap[pid].currentMeterValue(fo.meterType.research)
        fo.issueChangeFocusOrder(pid, IFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        itarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planetMap[pid].currentMeterValue(fo.meterType.targetResearch)
        newTargets.setdefault(pid,  {}).setdefault(IFocus,  (0, 0))
        newTargets[pid][IFocus] = ( itarget,  rtarget )
        if  currentFocus[pid] == MFocus:
            newTargets[pid][MFocus] = ( mtarget,  rtarget )
        fo.issueChangeFocusOrder(pid, RFocus) #may not be able to take, but try
    universe.updateMeterEstimates(empirePlanetIDs)
    for pid in empirePlanetIDs:
        itarget=planetMap[pid].currentMeterValue(fo.meterType.targetIndustry)
        rtarget=planetMap[pid].currentMeterValue(fo.meterType.targetResearch)
        newTargets.setdefault(pid,  {}).setdefault(RFocus,  (0, 0))
        newTargets[pid][RFocus] = ( itarget,  rtarget )
        if currentFocus[pid]  != RFocus:
            fo.issueChangeFocusOrder(pid, currentFocus[pid]) #put it back to what it was
    universe.updateMeterEstimates(empirePlanetIDs)
    return targetPP,  targetRP
Example #11
0
def _fill_data_dicts(planet_ids):
    universe = fo.getUniverse()
    newTargets.clear()
    currentFocus.clear()
    currentOutput.clear()
    planets = [(pid, planetMap[pid]) for pid in planet_ids]
    for pid, planet in planets:
        currentFocus[pid] = planet.focus
        currentOutput.setdefault(pid, {})[IFocus] = planet.currentMeterValue(fo.meterType.industry)
        currentOutput[pid][RFocus] = planet.currentMeterValue(fo.meterType.research)
        if IFocus in planet.availableFoci and planet.focus != IFocus:
            fo.issueChangeFocusOrder(pid, IFocus)  # may not be able to take, but try
    universe.updateMeterEstimates(planet_ids)
    for pid, planet in planets:
        itarget = planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget = planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == IFocus:
            newTargets.setdefault(pid, {})[IFocus] = (itarget, rtarget)
            newTargets.setdefault(pid, {})[GFocus] = [0, rtarget]
        else:
            newTargets.setdefault(pid, {})[IFocus] = (0, 0)
            newTargets.setdefault(pid, {})[GFocus] = [0, 0]
        # if currentFocus[pid] == MFocus:
        # newTargets[pid][MFocus] = (mtarget, rtarget)
        if RFocus in planet.availableFoci and planet.focus != RFocus:
            fo.issueChangeFocusOrder(pid, RFocus)  # may not be able to take, but try
    universe.updateMeterEstimates(planet_ids)
    for pid, planet in planets:
        can_focus = planet.currentMeterValue(fo.meterType.targetPopulation) > 0
        itarget = planet.currentMeterValue(fo.meterType.targetIndustry)
        rtarget = planet.currentMeterValue(fo.meterType.targetResearch)
        if planet.focus == RFocus:
            newTargets.setdefault(pid, {})[RFocus] = (itarget, rtarget)
            newTargets[pid][GFocus][0] = itarget
        else:
            newTargets.setdefault(pid, {})[RFocus] = (0, 0)
            newTargets[pid][GFocus][0] = 0
        if can_focus and currentFocus[pid] != planet.focus:
            fo.issueChangeFocusOrder(pid, currentFocus[pid])  # put it back to what it was
    universe.updateMeterEstimates(planet_ids)
    # Protection focus will give the same off-focus Industry and Research targets as Growth Focus
    for pid, planet in planets:
        newTargets[pid][PFocus] = newTargets[pid][GFocus]
Example #12
0
    def calculate_planet_infos(self, pids):
        """ Calculates for each possible focus the target output of each planet and stores it in planet info
        It excludes baked planets from consideration.
        Note: The results will not be strictly correct if any planets have global effects
        """
        # TODO this function depends on the specific rule that off-focus meter value are always the minimum value
        universe = fo.getUniverse()
        unbaked_pids = [pid for pid in pids if pid not in self.baked_planet_info]
        planet_infos = [(pid, self.all_planet_info[pid], self.all_planet_info[pid].planet) for pid in unbaked_pids]
        for pid, info, planet in planet_infos:
            if INDUSTRY in planet.availableFoci and planet.focus != INDUSTRY:
                fo.issueChangeFocusOrder(pid, INDUSTRY)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, info, planet in planet_infos:
            industry_target = planet.currentMeterValue(fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(fo.meterType.targetResearch)
            if planet.focus == INDUSTRY:
                info.possible_output[INDUSTRY] = (industry_target, research_target)
                info.possible_output[GROWTH] = research_target
            else:
                info.possible_output[INDUSTRY] = (0, 0)
                info.possible_output[GROWTH] = 0
            if RESEARCH in planet.availableFoci and planet.focus != RESEARCH:
                fo.issueChangeFocusOrder(pid, RESEARCH)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, info, planet in planet_infos:
            industry_target = planet.currentMeterValue(fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(fo.meterType.targetResearch)
            if planet.focus == RESEARCH:
                info.possible_output[RESEARCH] = (industry_target, research_target)
                info.possible_output[GROWTH] = (industry_target, info.possible_output[GROWTH])
            else:
                info.possible_output[RESEARCH] = (0, 0)
                info.possible_output[GROWTH] = (0, info.possible_output[GROWTH])
            if info.planet.availableFoci and info.current_focus != planet.focus:
                fo.issueChangeFocusOrder(pid, info.current_focus)  # put it back to what it was

        universe.updateMeterEstimates(unbaked_pids)
        # Protection focus will give the same off-focus Industry and Research targets as Growth Focus
        for pid, info, planet in planet_infos:
            info.possible_output[PRODUCTION] = info.possible_output[GROWTH]
Example #13
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
Example #14
0
def generateResourcesOrders():
    "generate resources focus orders"

    # get the highest resource priorities
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    ownedPlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    capitalID = PlanetUtilsAI.getCapitalID()
    print "Resources Management:"
    print ""
    print "Resource Priorities:"
    resourcePriorities = {}
    for priorityType in getAIPriorityResourceTypes():
        resourcePriorities[priorityType] = foAI.foAIstate.getPriority(priorityType)

    sortedPriorities = resourcePriorities.items()
    sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True)
    topPriority = -1
    for evaluationPair in sortedPriorities:
        if topPriority < 0:
            topPriority = evaluationPair[0]
        print "    ID|Score: " + str(evaluationPair)

    print "  Top Resource Priority: " + str(topPriority)
    if topPriority == AIPriorityType.PRIORITY_RESOURCE_FOOD:
        newFocus = AIFocusType.FOCUS_FARMING
        print "  New Resource Focus:    " + str(newFocus)
        for planetID in ownedPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and newFocus in planet.availableFoci:
                print "  Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus)
                fo.issueChangeFocusOrder(planetID, newFocus)
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_MINERALS:
        newFocus = AIFocusType.FOCUS_MINING
        print "  Top Resource Focus:    " + str(newFocus)
        for planetID in ownedPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and newFocus in planet.availableFoci:
                print "  Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus)
                fo.issueChangeFocusOrder(planetID, newFocus) 
    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_PRODUCTION:
        newFocus = AIFocusType.FOCUS_INDUSTRY
        print "  New Resource Focus:    " + str(newFocus)
        for planetID in ownedPlanetIDs:
            planet = universe.getPlanet(planetID)
            focus = newFocus
            if planetID == capitalID and newFocus in planet.availableFoci:
                print "  Capital ID: " + str(planetID) + " Resource Focus: " + str(newFocus)
                fo.issueChangeFocusOrder(planetID, newFocus)

    elif topPriority == AIPriorityType.PRIORITY_RESOURCE_RESEARCH:
        newFocus = AIFocusType.FOCUS_RESEARCH
        print "  New Resource Focus:    " + str(newFocus)

    # what is the focus of available resource centers?
    print ""
    print "Planet Resources Foci:"

    print ""  
    print "  Empire Owned planetIDs:" + str(ownedPlanetIDs)       
    for planetID in ownedPlanetIDs:
        planet = universe.getPlanet(planetID)
        planetPopulation = planet.currentMeterValue(fo.meterType.population)                
        print "  ID: " + str(planetID) + " Name: " + str(planet.name) + " Type: " + str(planet.type) + " Size: " + str(planet.size) + " Focus: " + str(planet.focus) + " Species: " + str(planet.speciesName) + " Population: " + str(planetPopulation)
Example #15
0
    def bake_future_focus(self, pid, focus, update=True, force=False):
        """Set the focus and moves it from the raw list to the baked list of planets.

        pid -- pid
        focus -- future focus to use
        update -- If update is True then the meters of the raw planets will be updated.
                  If the planet's change of focus will have a global effect (growth,
                  production or research special), then update should be True.
        Return success or failure
        """
        pinfo = self.raw_planet_info.get(pid)
        if not pinfo:
            return False
        if (focus == INDUSTRY or focus == RESEARCH) and not force:
            idx = 0 if focus == INDUSTRY else 1
            # check for influence instead
            focus_gain = pinfo.possible_output[focus][
                idx] - pinfo.possible_output[INFLUENCE][idx]
            influence_gain = pinfo.possible_output[INFLUENCE][
                2] - pinfo.possible_output[focus][2]
            debug(
                f"{pinfo.planet.name} current: {_focus_name(pinfo.current_focus)}, requested: {_focus_name(focus)}, "
                f"requested_gain: {focus_gain}, influence_gain: {influence_gain}"
            )
            if influence_gain * self.priority[2] > focus_gain * self.priority[
                    idx]:
                debug(f"Choosing influence over {_focus_name(focus)}."
                      f" {influence_gain:.2f} * {self.priority[2]:.1f}"
                      f" > {focus_gain:.2f} * {self.priority[idx]:.1f}")
                focus = INFLUENCE
        last_turn = fo.currentTurn()
        if (  # define idx constants for accessing these tuples
                focus != PROTECTION and focus != pinfo.current_focus
                and policy_is_adopted(bureaucracy)
                and pinfo.current_output[2] + 0.2 <
                pinfo.possible_output[pinfo.current_focus][2]
                and pinfo.planet.LastTurnColonized != last_turn
                and pinfo.planet.LastTurnConquered != last_turn):
            # avoid going down too much by repeated focus changes while having bureaucracy
            info(
                "Avoid focus change on %s due to bureaucracy. IPprod: current=%.2f, target=%.2f",
                pinfo.planet.name,
                pinfo.current_output[2],
                pinfo.possible_output[pinfo.current_focus][2],
            )
            return False

        success = bool(pinfo.current_focus == focus
                       or (focus in pinfo.planet.availableFoci
                           and fo.issueChangeFocusOrder(pid, focus)))
        if success:
            if update and pinfo.current_focus != focus:
                universe = fo.getUniverse()
                universe.updateMeterEstimates(self.raw_planet_info.keys())
                industry_target = pinfo.planet.currentMeterValue(
                    fo.meterType.targetIndustry)
                research_target = pinfo.planet.currentMeterValue(
                    fo.meterType.targetResearch)
                influence_target = pinfo.planet.currentMeterValue(
                    fo.meterType.targetInfluence)
                pinfo.possible_output[focus] = (industry_target,
                                                research_target,
                                                influence_target)

            pinfo.future_focus = focus
            self.baked_planet_info[pid] = self.raw_planet_info.pop(pid)
        return success
Example #16
0
    def calculate_planet_infos(self, pids):
        """Calculates for each possible focus the target output of each planet and stores it in planet info
        It excludes baked planets from consideration.
        Note: The results will not be strictly correct if any planets have global effects
        """
        # TODO this function depends on the specific rule that off-focus meter value are always the minimum value
        universe = fo.getUniverse()
        unbaked_pids = [
            pid for pid in pids if pid not in self.baked_planet_info
        ]
        planet_infos = [(pid, self.all_planet_info[pid],
                         self.all_planet_info[pid].planet)
                        for pid in unbaked_pids]
        for pid, pinfo, planet in planet_infos:
            if INDUSTRY in planet.availableFoci and planet.focus != INDUSTRY:
                fo.issueChangeFocusOrder(
                    pid, INDUSTRY)  # may not be able to take, but try

        def merge(po1, po2):
            """merge two partially determined possible_outputs"""
            return (
                po1[0] or po2[0],
                po1[1] or po2[1],
                po1[2] or po2[2],
            )

        universe.updateMeterEstimates(unbaked_pids)
        for pid, pinfo, planet in planet_infos:
            po = pinfo.possible_output
            industry_target = planet.currentMeterValue(
                fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(
                fo.meterType.targetResearch)
            influence_target = planet.currentMeterValue(
                fo.meterType.targetInfluence)
            if planet.focus == INDUSTRY:
                # each focus only affects its own meter
                po[INDUSTRY] = (industry_target, research_target,
                                influence_target)
                po[GROWTH] = (0, research_target, influence_target)
                po[INFLUENCE] = (0, research_target, 0)
            else:
                po[INDUSTRY] = (0, 0, 0)
                po[GROWTH] = (0, 0, 0)
                po[INFLUENCE] = (0, 0, 0)
            if RESEARCH in planet.availableFoci and planet.focus != RESEARCH:
                fo.issueChangeFocusOrder(
                    pid, RESEARCH)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, pinfo, planet in planet_infos:
            po = pinfo.possible_output
            industry_target = planet.currentMeterValue(
                fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(
                fo.meterType.targetResearch)
            influence_target = planet.currentMeterValue(
                fo.meterType.targetInfluence)
            if planet.focus == RESEARCH:
                po[RESEARCH] = (industry_target, research_target,
                                influence_target)
                po[GROWTH] = merge(po[GROWTH],
                                   (industry_target, 0, influence_target))
                po[INFLUENCE] = merge(po[INFLUENCE], (industry_target, 0, 0))
            else:
                po[RESEARCH] = (0, 0, 0)
            if INFLUENCE in planet.availableFoci and planet.focus != INFLUENCE:
                fo.issueChangeFocusOrder(
                    pid, INFLUENCE)  # may not be able to take, but try

        universe.updateMeterEstimates(unbaked_pids)
        for pid, pinfo, planet in planet_infos:
            po = pinfo.possible_output
            industry_target = planet.currentMeterValue(
                fo.meterType.targetIndustry)
            research_target = planet.currentMeterValue(
                fo.meterType.targetResearch)
            influence_target = planet.currentMeterValue(
                fo.meterType.targetInfluence)
            if planet.focus == INFLUENCE:
                po[INFLUENCE] = (industry_target, research_target,
                                 influence_target)
            else:
                po[INFLUENCE] = (0, 0, 0)
            if pinfo.planet.availableFoci and pinfo.current_focus != planet.focus:
                fo.issueChangeFocusOrder(
                    pid, pinfo.current_focus)  # put it back to what it was

        universe.updateMeterEstimates(unbaked_pids)
        # Protection focus will give the same off-focus Industry and Research targets as Growth Focus
        for pid, pinfo, planet in planet_infos:
            po = pinfo.possible_output
            po[PROTECTION] = po[GROWTH]
            for focus in [INDUSTRY, RESEARCH, INFLUENCE, PROTECTION]:
                debug(
                    "Resource output of planet %s for focus %s is %f/%f/%f",
                    pinfo.planet,
                    focus,
                    po[focus][0],
                    po[focus][1],
                    po[focus][2],
                )
Example #17
0
def set_planet_resource_foci():
    """set resource focus of planets """
    newFoci = {}

    print "\n============================"
    print "Collecting info to assess Planet Focus Changes\n"
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    currentTurn = fo.currentTurn()
    # set the random seed (based on galaxy seed, empire ID and current turn)
    # for game-reload consistency 
    freq = min(3, (max(5, currentTurn - 80)) / 4.0) ** (1.0 / 3)
    if not (limitAssessments and (abs(currentTurn - lastFociCheck[0]) < 1.5 * freq) and (random.random() < 1.0 / freq)):
        lastFociCheck[0] = currentTurn
        resource_timer.start("getPlanets")
        empirePlanetIDs = list(PlanetUtilsAI.get_owned_planets_by_empire(universe.planetIDs))
        resource_timer.start("Filter")
        resource_timer.start("Priority")
        # TODO: take into acct splintering of resource groups
        # fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        # fleetSupplyablePlanetIDs = PlanetUtilsAI.get_planets_in__systems_ids(fleetSupplyableSystemIDs)
        ppPrio = foAI.foAIstate.get_priority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION)
        rpPrio = foAI.foAIstate.get_priority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH)
        priorityRatio = float(rpPrio) / (ppPrio + 0.0001)
        resource_timer.start("Shuffle")
        # not supporting Growth for general planets until also adding code to make sure would actually benefit
        # shuffle(generalPlanetIDs)
        resource_timer.start("Targets")
        planets = map(universe.getPlanet, empirePlanetIDs)
        planetMap.clear()
        planetMap.update(zip(empirePlanetIDs, planets))
        if useGrowth:
            for metab, metabIncPop in ColonisationAI.empire_metabolisms.items():
                for special in [aspec for aspec in AIDependencies.metabolismBoostMap.get(metab, []) if aspec in ColonisationAI.available_growth_specials]:
                    rankedPlanets = []
                    for pid in ColonisationAI.available_growth_specials[special]:
                        planet = planetMap[pid]
                        cur_focus = planet.focus
                        pop = planet.currentMeterValue(fo.meterType.population)
                        if (pop > metabIncPop - 2 * planet.size) or (GFocus not in planet.availableFoci):  # not enough benefit to lose local production, or can't put growth focus here
                            continue
                        for special2 in ["COMPUTRONIUM_SPECIAL"]:
                            if special2 in planet.specials:
                                break
                        else:  # didn't have any specials that would override interest in growth special
                            print "Considering Growth Focus for %s (%d) with special %s; planet has pop %.1f and %s metabolism incremental pop is %.1f" % (
                                planet.name, pid, special, pop, metab, metabIncPop)
                            if cur_focus == GFocus:
                                pop -= 4  # discourage changing current focus to minimize focus-changing penalties
                            rankedPlanets.append((pop, pid, cur_focus))
                    if not rankedPlanets:
                        continue
                    rankedPlanets.sort()
                    print "Considering Growth Focus choice for special %s; possible planet pop, id pairs are %s" % (metab, rankedPlanets)
                    for spSize, spPID, cur_focus in rankedPlanets:  # index 0 should be able to set focus, but just in case...
                        result = 1
                        if cur_focus != GFocus:
                            result = fo.issueChangeFocusOrder(spPID, GFocus)
                        if result == 1:
                            newFoci[spPID] = GFocus
                            if spPID in empirePlanetIDs:
                                del empirePlanetIDs[empirePlanetIDs.index(spPID)]
                            print "%s focus of planet %s (%d) at Growth Focus" % (["set", "left"][cur_focus == GFocus], planetMap[spPID].name, spPID)
                            break
                        else:
                            print "failed setting focus of planet %s (%d) at Growth Focus; focus left at %s" % (planetMap[spPID].name, spPID, planetMap[spPID].focus)
        already_have_comp_moon = False
        for pid in empirePlanetIDs:
            planet = planetMap[pid]
            if "COMPUTRONIUM_SPECIAL" in planet.specials and RFocus in planet.availableFoci and not already_have_comp_moon:
                curFocus = planet.focus
                newFoci[pid] = RFocus
                result = 0
                if curFocus != RFocus:
                    result = fo.issueChangeFocusOrder(pid, RFocus)
                    if result == 1:
                        universe.updateMeterEstimates(empirePlanetIDs)
                if curFocus == RFocus or result == 1:
                    already_have_comp_moon = True
                    print "%s focus of planet %s (%d) (with Computronium Moon) at Research Focus" % (["set", "left"][curFocus == RFocus], planetMap[pid].name, pid)
                    if pid in empirePlanetIDs:
                        del empirePlanetIDs[empirePlanetIDs.index(pid)]
                    continue
            if ((([bld.buildingTypeName for bld in map(universe.getObject, planet.buildingIDs) if bld.buildingTypeName in
                    ["BLD_CONC_CAMP", "BLD_CONC_CAMP_REMNANT"]] != []) or
                             ([ccspec for ccspec in planet.specials if ccspec in ["CONC_CAMP_MASTER_SPECIAL", "CONC_CAMP_SLAVE_SPECIAL"]] != []))
                    and IFocus in planet.availableFoci):
                curFocus = planet.focus
                newFoci[pid] = IFocus
                result = 0
                if curFocus != IFocus:
                    result = fo.issueChangeFocusOrder(pid, IFocus)
                    if result == 1:
                        print ("Tried setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, got result %d and focus %s" %
                               (newFoci[pid], planet.name, pid, planet.speciesName, curFocus, result, planetMap[pid].focus))
                        universe.updateMeterEstimates(empirePlanetIDs)
                    if (result != 1) or planetMap[pid].focus != IFocus:
                        newplanet = universe.getPlanet(pid)
                        print ("Error: Failed setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, but new planet copy shows %s" %
                               (newFoci[pid], planetMap[pid].name, pid, planetMap[pid].speciesName, planetMap[pid].focus, newplanet.focus))
                if curFocus == IFocus or result == 1:
                    print "%s focus of planet %s (%d) (with Concentration Camps/Remnants) at Industry Focus" % (["set", "left"][curFocus == IFocus], planetMap[pid].name, pid)
                    if pid in empirePlanetIDs:
                        del empirePlanetIDs[empirePlanetIDs.index(pid)]
                    continue
        # pp, rp = get_resource_target_totals(empirePlanetIDs, planetMap)
        pp, rp = get_resource_target_totals(planetMap.keys())

        for pid in empirePlanetIDs:
            planet = planetMap[pid]
            if PFocus in planet.availableFoci and assess_protection_focus(pid):
                curFocus = planet.focus
                newFoci[pid] = PFocus
                result = 0
                if curFocus != PFocus:
                    result = fo.issueChangeFocusOrder(pid, PFocus)
                    if result == 1:
                        print ("Tried setting %s for planet %s (%d) with species %s and current focus %s, got result %d and focus %s" %
                               (newFoci[pid], planet.name, pid, planet.speciesName, curFocus, result, planet.focus))
                        universe.updateMeterEstimates(empirePlanetIDs)
                    if (result != 1) or planet.focus != PFocus:
                        newplanet = universe.getPlanet(pid)
                        print ("Error: Failed setting %s for planet %s (%d) with species %s and current focus %s, but new planet copy shows %s" %
                               (newFoci[pid], planet.name, pid, planet.speciesName, planet.focus, newplanet.focus))
                if curFocus == PFocus or result == 1:
                    print "%s focus of planet %s (%d) at Protection(Defense) Focus" % (["set", "left"][curFocus == PFocus], planet.name, pid)
                    if pid in empirePlanetIDs:
                        del empirePlanetIDs[empirePlanetIDs.index(pid)]
                    continue

        print "\n-----------------------------------------"
        print "Making Planet Focus Change Determinations\n"

        ratios = []
        # for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that
        # include a bias to slightly discourage changing foci
        curTargetPP = 0.001
        curTargetRP = 0.001
        resource_timer.start("Loop")  # loop
        has_force = tech_is_complete("CON_FRC_ENRG_STRC")
        preset_ids = set(planetMap.keys()) - set(empirePlanetIDs)
        ctPP0, ctRP0 = 0, 0
        for pid in preset_ids:
            nPP, nRP = newTargets.get(pid, {}).get(planetMap[pid].focus, [0, 0])
            curTargetPP += nPP
            curTargetRP += nRP
            iPP, iRP = newTargets.get(pid, {}).get(IFocus, [0, 0])
            ctPP0 += iPP
            ctRP0 += iRP

        id_set = set(empirePlanetIDs)
        for adj_round in [1, 2, 3, 4]:
            maxi_ratio = ctRP0 / max(0.01, ctPP0)  # should only change between rounds 1 and 2
            for pid in list(id_set):
                if adj_round == 1:  # tally max Industry
                    iPP, iRP = newTargets.get(pid, {}).get(IFocus, [0, 0])
                    ctPP0 += iPP
                    ctRP0 += iRP
                    continue
                II, IR = newTargets[pid][IFocus]
                RI, RR = newTargets[pid][RFocus]
                CI, CR = currentOutput[pid][IFocus], currentOutput[pid][RFocus]
                research_penalty = (currentFocus[pid] != RFocus)
                # calculate factor F at which II + F * IR == RI + F * RR =====> F = ( II-RI ) / (RR-IR)
                thisFactor = (II - RI) / max(0.01, RR - IR)  # don't let denominator be zero for planets where focus doesn't change RP
                planet = planetMap[pid]
                if adj_round == 2:  # take research at planets with very cheap research
                    if (maxi_ratio < priorityRatio) and (curTargetRP < priorityRatio * ctPP0) and (thisFactor <= 1.0):
                        curTargetPP += RI
                        curTargetRP += RR
                        newFoci[pid] = RFocus
                        id_set.discard(pid)
                    continue
                if adj_round == 3:  # take research at planets where can do reasonable balance
                    if has_force or (foAI.foAIstate.aggression < fo.aggression.aggressive) or (curTargetRP >= priorityRatio * ctPP0):
                        continue
                    pop = planet.currentMeterValue(fo.meterType.population)
                    t_pop = planet.currentMeterValue(fo.meterType.targetPopulation)
                    # if AI is aggressive+, and this planet in range where temporary Research focus can get an additional RP at cost of 1 PP, and still need some RP, then do it
                    if pop < t_pop - 5:
                        continue
                    if (CI > II + 8) or (((RR > II) or ((RR - CR) >= 1 + 2 * research_penalty)) and ((RR - IR) >= 3) and ((CR - IR) >= 0.7 * ((II - CI) * (1 + 0.1 * research_penalty)))):
                        curTargetPP += CI - 1 - research_penalty
                        curTargetRP += CR + 1
                        newFoci[pid] = RFocus
                        id_set.discard(pid)
                    continue
                # adj_round == 4 assume default IFocus
                curTargetPP += II  # icurTargets initially calculated by Industry focus, which will be our default focus
                curTargetRP += IR
                newFoci[pid] = IFocus
                ratios.append((thisFactor, pid))

        ratios.sort()
        printedHeader = False
        fociMap = {IFocus: "Industry", RFocus: "Research", MFocus: "Mining", GFocus: "Growth", PFocus: "Defense"}
        gotAlgo = tech_is_complete("LRN_ALGO_ELEGANCE")
        for ratio, pid in ratios:
            do_research = False  # (newFoci[pid]==RFocus)
            if (priorityRatio < (curTargetRP / (curTargetPP + 0.0001))) and not do_research:  # we have enough RP
                if ratio < 1.1 and foAI.foAIstate.aggression > fo.aggression.cautious:  # but wait, RP is still super cheap relative to PP, maybe will take more RP
                    if priorityRatio < 1.5 * (curTargetRP / (curTargetPP + 0.0001)):  # yeah, really a glut of RP, stop taking RP
                        break
                else:  # RP not super cheap & we have enough, stop taking it
                    break
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            # if currentFocus[pid] == MFocus:
            # II = max( II, newTargets[pid][MFocus][0] )
            if do_research or (gotAlgo and (
                   (ratio > 2.0 and curTargetPP < 15) or
                   (ratio > 2.5 and curTargetPP < 25 and II > 5) or
                   (ratio > 3.0 and curTargetPP < 40 and II > 5) or
                   (ratio > 4.0 and curTargetPP < 100 and II > 10) or
                   ((curTargetRP + RR - IR) / max(0.001, curTargetPP - II + RI) > 2 * priorityRatio))):  # we already have algo elegance and more RP would be too expensive, or overkill
                if not printedHeader:
                    printedHeader = True
                    print "Rejecting further Research Focus choices as too expensive:"
                    print "%34s|%20s|%15s |%15s|%15s |%15s |%15s" % ("                      Planet ", " current RP/PP ", " current target RP/PP ", "current Focus ", "  rejectedFocus ", " rejected target RP/PP ", "rejected RP-PP EQF")
                    oldFocus = currentFocus[pid]
                    cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus]
                    otPP, otRP = newTargets[pid].get(oldFocus, (0, 0))
                    ntPP, ntRP = newTargets[pid].get(RFocus, (0, 0))
                    print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f |  cF: %8s | nF: %8s | cT: %5.1f / %5.1f | %.2f" % (pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[RFocus], ntRP, ntPP, ratio)
                    continue  # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose
            # if planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0: #only set to research if pop won't die out
            newFoci[pid] = RFocus
            curTargetRP += (RR - IR)
            curTargetPP -= (II - RI)
        print "============================"
        print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f ( %.1f / %.1f )" % (priorityRatio, rp / (pp + 0.0001), rp, pp)
        print "Max Industry assignments would result in target RP/PP ratio of %.2f ( %.1f / %.1f )" % (ctRP0 / (ctPP0 + 0.0001), ctRP0, ctPP0)
        print "-------------------------------------"
        print "%34s|%20s|%15s |%15s|%15s |%15s " % ("                      Planet ", " current RP/PP ", " current target RP/PP ", "current Focus ", "  newFocus ", " new target RP/PP ")
        totalChanged = 0
        for id_set in empirePlanetIDs, preset_ids:
            for pid in id_set:
                canFocus = planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) > 0
                oldFocus = currentFocus[pid]
                newFocus = newFoci.get(pid, IFocus)
                cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][RFocus]
                otPP, otRP = newTargets[pid].get(oldFocus, (0, 0))
                ntPP, ntRP = otPP, otRP
                if newFocus != oldFocus and newFocus in planetMap[pid].availableFoci:  # planetMap[pid].focus
                    totalChanged += 1
                    if newFocus != planetMap[pid].focus:
                        result = fo.issueChangeFocusOrder(pid, newFocus)
                        if result == 1:
                            ntPP, ntRP = newTargets[pid].get(newFocus, (0, 0))
                        else:
                            print "Trouble changing focus of planet %s (%d) to %s" % (planetMap[pid].name, pid, newFocus)
                print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f |  cF: %8s | nF: %8s | cT: %5.1f / %5.1f " % (pid, planetMap[pid].name, cRP, cPP, otRP, otPP, fociMap.get(oldFocus, 'unknown'), fociMap[newFocus], ntRP, ntPP)
            print "-------------------------------------"
        print "-------------------------------------"
        print "Final Ratio Target (turn %4d) RP/PP : %.2f ( %.1f / %.1f ) after %d Focus changes" % (fo.currentTurn(), curTargetRP / (curTargetPP + 0.0001), curTargetRP, curTargetPP, totalChanged)
        resource_timer.end()
    aPP, aRP = empire.productionPoints, empire.resourceProduction(fo.resourceType.research)
    # Next string used in charts. Don't modify it!
    print "Current Output (turn %4d) RP/PP : %.2f ( %.1f / %.1f )" % (fo.currentTurn(), aRP / (aPP + 0.0001), aRP, aPP)
    print "------------------------"
    print "ResourcesAI Time Requirements:"
Example #18
0
def set_planet_resource_foci():
    """set resource focus of planets """
    newFoci = {}

    print "\n============================"
    print "Collecting info to assess Planet Focus Changes\n"
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    currentTurn = fo.currentTurn()
    # set the random seed (based on galaxy seed, empire ID and current turn)
    # for game-reload consistency
    freq = min(3, (max(5, currentTurn - 80)) / 4.0)**(1.0 / 3)
    if not (limitAssessments and
            (abs(currentTurn - lastFociCheck[0]) < 1.5 * freq) and
            (random.random() < 1.0 / freq)):
        lastFociCheck[0] = currentTurn
        resource_timer.start("getPlanets")
        empirePlanetIDs = list(
            PlanetUtilsAI.get_owned_planets_by_empire(universe.planetIDs))
        resource_timer.start("Filter")
        resource_timer.start("Priority")
        # TODO: take into acct splintering of resource groups
        # fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        # fleetSupplyablePlanetIDs = PlanetUtilsAI.get_planets_in__systems_ids(fleetSupplyableSystemIDs)
        ppPrio = foAI.foAIstate.get_priority(
            AIPriorityType.PRIORITY_RESOURCE_PRODUCTION)
        rpPrio = foAI.foAIstate.get_priority(
            AIPriorityType.PRIORITY_RESOURCE_RESEARCH)
        priorityRatio = float(rpPrio) / (ppPrio + 0.0001)
        resource_timer.start("Shuffle")
        # not supporting Growth for general planets until also adding code to make sure would actually benefit
        # shuffle(generalPlanetIDs)
        resource_timer.start("Targets")
        planets = map(universe.getPlanet, empirePlanetIDs)
        planetMap.clear()
        planetMap.update(zip(empirePlanetIDs, planets))
        if useGrowth:
            for metab, metabIncPop in ColonisationAI.empire_metabolisms.items(
            ):
                for special in [
                        aspec
                        for aspec in AIDependencies.metabolismBoostMap.get(
                            metab, [])
                        if aspec in ColonisationAI.available_growth_specials
                ]:
                    rankedPlanets = []
                    for pid in ColonisationAI.available_growth_specials[
                            special]:
                        planet = planetMap[pid]
                        cur_focus = planet.focus
                        pop = planet.currentMeterValue(fo.meterType.population)
                        if (pop > metabIncPop - 2 * planet.size) or (
                                GFocus not in planet.availableFoci
                        ):  # not enough benefit to lose local production, or can't put growth focus here
                            continue
                        for special2 in ["COMPUTRONIUM_SPECIAL"]:
                            if special2 in planet.specials:
                                break
                        else:  # didn't have any specials that would override interest in growth special
                            print "Considering Growth Focus for %s (%d) with special %s; planet has pop %.1f and %s metabolism incremental pop is %.1f" % (
                                planet.name, pid, special, pop, metab,
                                metabIncPop)
                            if cur_focus == GFocus:
                                pop -= 4  # discourage changing current focus to minimize focus-changing penalties
                            rankedPlanets.append((pop, pid, cur_focus))
                    if not rankedPlanets:
                        continue
                    rankedPlanets.sort()
                    print "Considering Growth Focus choice for special %s; possible planet pop, id pairs are %s" % (
                        metab, rankedPlanets)
                    for spSize, spPID, cur_focus in rankedPlanets:  # index 0 should be able to set focus, but just in case...
                        result = 1
                        if cur_focus != GFocus:
                            result = fo.issueChangeFocusOrder(spPID, GFocus)
                        if result == 1:
                            newFoci[spPID] = GFocus
                            if spPID in empirePlanetIDs:
                                del empirePlanetIDs[empirePlanetIDs.index(
                                    spPID)]
                            print "%s focus of planet %s (%d) at Growth Focus" % (
                                ["set", "left"][cur_focus == GFocus],
                                planetMap[spPID].name, spPID)
                            break
                        else:
                            print "failed setting focus of planet %s (%d) at Growth Focus; focus left at %s" % (
                                planetMap[spPID].name, spPID,
                                planetMap[spPID].focus)
        for pid in empirePlanetIDs:
            planet = planetMap[pid]
            if "COMPUTRONIUM_SPECIAL" in planet.specials:  # TODO: ensure only one (extremely rarely needed)
                curFocus = planet.focus
                if RFocus not in planet.availableFoci:
                    continue
                newFoci[pid] = RFocus
                result = 0
                if curFocus != RFocus:
                    result = fo.issueChangeFocusOrder(pid, RFocus)
                    if result == 1:
                        universe.updateMeterEstimates(empirePlanetIDs)
                if curFocus == RFocus or result == 1:
                    print "%s focus of planet %s (%d) (with Computronium Moon) at Research Focus" % (
                        ["set", "left"
                         ][curFocus == RFocus], planetMap[pid].name, pid)
                    if pid in empirePlanetIDs:
                        del empirePlanetIDs[empirePlanetIDs.index(pid)]
            elif (([
                    bld.buildingTypeName
                    for bld in map(universe.getObject, planet.buildingIDs)
                    if bld.buildingTypeName in
                ["BLD_CONC_CAMP", "BLD_CONC_CAMP_REMNANT"]
            ] != []) or ([
                    ccspec for ccspec in planet.specials if ccspec in
                ["CONC_CAMP_MASTER_SPECIAL", "CONC_CAMP_SLAVE_SPECIAL"]
            ] != [])):
                if IFocus not in planet.availableFoci:
                    continue
                curFocus = planet.focus
                newFoci[pid] = IFocus
                result = 0
                if curFocus != IFocus:
                    result = fo.issueChangeFocusOrder(pid, IFocus)
                    if result == 1:
                        print(
                            "Tried setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, got result %d and focus %s"
                            % (newFoci[pid], planet.name, pid,
                               planet.speciesName, curFocus, result,
                               planetMap[pid].focus))
                        universe.updateMeterEstimates(empirePlanetIDs)
                    if (result != 1) or planetMap[pid].focus != IFocus:
                        newplanet = universe.getPlanet(pid)
                        print(
                            "Error: Failed setting %s for Concentration Camp planet %s (%d) with species %s and current focus %s, but new planet copy shows %s"
                            % (newFoci[pid], planetMap[pid].name, pid,
                               planetMap[pid].speciesName,
                               planetMap[pid].focus, newplanet.focus))
                if curFocus == IFocus or result == 1:
                    print "%s focus of planet %s (%d) (with Concentration Camps/Remnants) at Industry Focus" % (
                        ["set", "left"
                         ][curFocus == IFocus], planetMap[pid].name, pid)
                    if pid in empirePlanetIDs:
                        del empirePlanetIDs[empirePlanetIDs.index(pid)]

        # pp, rp = get_resource_target_totals(empirePlanetIDs, planetMap)
        pp, rp = get_resource_target_totals(planetMap.keys())
        print "\n-----------------------------------------"
        print "Making Planet Focus Change Determinations\n"

        ratios = []
        # for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that
        # include a bias to slightly discourage changing foci
        curTargetPP = 0.001
        curTargetRP = 0.001
        resource_timer.start("Loop")  # loop
        has_force = tech_is_complete("CON_FRC_ENRG_STRC")
        preset_ids = set(planetMap.keys()) - set(empirePlanetIDs)
        ctPP0, ctRP0 = 0, 0
        for pid in preset_ids:
            nPP, nRP = newTargets.get(pid, {}).get(planetMap[pid].focus,
                                                   [0, 0])
            curTargetPP += nPP
            curTargetRP += nRP
            iPP, iRP = newTargets.get(pid, {}).get(IFocus, [0, 0])
            ctPP0 += iPP
            ctRP0 += iRP

        id_set = set(empirePlanetIDs)
        for adj_round in [1, 2, 3, 4]:
            maxi_ratio = ctRP0 / max(
                0.01, ctPP0)  # should only change between rounds 1 and 2
            for pid in list(id_set):
                if adj_round == 1:  # tally max Industry
                    iPP, iRP = newTargets.get(pid, {}).get(IFocus, [0, 0])
                    ctPP0 += iPP
                    ctRP0 += iRP
                    continue
                II, IR = newTargets[pid][IFocus]
                RI, RR = newTargets[pid][RFocus]
                CI, CR = currentOutput[pid][IFocus], currentOutput[pid][RFocus]
                research_penalty = (currentFocus[pid] != RFocus)
                # calculate factor F at which II + F * IR == RI + F * RR =====> F = ( II-RI ) / (RR-IR)
                thisFactor = (II - RI) / max(
                    0.01, RR - IR
                )  # don't let denominator be zero for planets where focus doesn't change RP
                planet = planetMap[pid]
                if adj_round == 2:  # take research at planets with very cheap research
                    if (maxi_ratio < priorityRatio) and (
                            curTargetRP <
                            priorityRatio * ctPP0) and (thisFactor <= 1.0):
                        curTargetPP += RI
                        curTargetRP += RR
                        newFoci[pid] = RFocus
                        id_set.discard(pid)
                    continue
                if adj_round == 3:  # take research at planets where can do reasonable balance
                    if has_force or (foAI.foAIstate.aggression <
                                     fo.aggression.aggressive) or (
                                         curTargetRP >= priorityRatio * ctPP0):
                        continue
                    pop = planet.currentMeterValue(fo.meterType.population)
                    t_pop = planet.currentMeterValue(
                        fo.meterType.targetPopulation)
                    # if AI is aggressive+, and this planet in range where temporary Research focus can get an additional RP at cost of 1 PP, and still need some RP, then do it
                    if pop < t_pop - 5:
                        continue
                    if (CI > II + 8) or (((RR > II) or (
                        (RR - CR) >= 1 + 2 * research_penalty)) and
                                         ((RR - IR) >= 3) and
                                         ((CR - IR) >= 0.7 *
                                          ((II - CI) *
                                           (1 + 0.1 * research_penalty)))):
                        curTargetPP += CI - 1 - research_penalty
                        curTargetRP += CR + 1
                        newFoci[pid] = RFocus
                        id_set.discard(pid)
                    continue
                # adj_round == 4 assume default IFocus
                curTargetPP += II  # icurTargets initially calculated by Industry focus, which will be our default focus
                curTargetRP += IR
                newFoci[pid] = IFocus
                ratios.append((thisFactor, pid))

        ratios.sort()
        printedHeader = False
        fociMap = {
            IFocus: "Industry",
            RFocus: "Research",
            MFocus: "Mining",
            GFocus: "Growth"
        }
        gotAlgo = tech_is_complete("LRN_ALGO_ELEGANCE")
        for ratio, pid in ratios:
            do_research = False  # (newFoci[pid]==RFocus)
            if (priorityRatio < (curTargetRP / (curTargetPP + 0.0001))
                ) and not do_research:  # we have enough RP
                if ratio < 1.1 and foAI.foAIstate.aggression > fo.aggression.cautious:  # but wait, RP is still super cheap relative to PP, maybe will take more RP
                    if priorityRatio < 1.5 * (
                            curTargetRP / (curTargetPP + 0.0001)
                    ):  # yeah, really a glut of RP, stop taking RP
                        break
                else:  # RP not super cheap & we have enough, stop taking it
                    break
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            # if currentFocus[pid] == MFocus:
            # II = max( II, newTargets[pid][MFocus][0] )
            if do_research or (
                    gotAlgo and
                ((ratio > 2.0 and curTargetPP < 15) or
                 (ratio > 2.5 and curTargetPP < 25 and II > 5) or
                 (ratio > 3.0 and curTargetPP < 40 and II > 5) or
                 (ratio > 4.0 and curTargetPP < 100 and II > 10) or
                 ((curTargetRP + RR - IR) / max(0.001, curTargetPP - II + RI) >
                  2 * priorityRatio))
            ):  # we already have algo elegance and more RP would be too expensive, or overkill
                if not printedHeader:
                    printedHeader = True
                    print "Rejecting further Research Focus choices as too expensive:"
                    print "%34s|%20s|%15s |%15s|%15s |%15s |%15s" % (
                        "                      Planet ", " current RP/PP ",
                        " current target RP/PP ", "current Focus ",
                        "  rejectedFocus ", " rejected target RP/PP ",
                        "rejected RP-PP EQF")
                    oldFocus = currentFocus[pid]
                    cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][
                        RFocus]
                    otPP, otRP = newTargets[pid].get(oldFocus, (0, 0))
                    ntPP, ntRP = newTargets[pid].get(RFocus, (0, 0))
                    print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f |  cF: %8s | nF: %8s | cT: %5.1f / %5.1f | %.2f" % (
                        pid, planetMap[pid].name, cRP, cPP, otRP, otPP,
                        fociMap.get(oldFocus, 'unknown'), fociMap[RFocus],
                        ntRP, ntPP, ratio)
                    continue  # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose
            # if planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0: #only set to research if pop won't die out
            newFoci[pid] = RFocus
            curTargetRP += (RR - IR)
            curTargetPP -= (II - RI)
        print "============================"
        print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f ( %.1f / %.1f )" % (
            priorityRatio, rp / (pp + 0.0001), rp, pp)
        print "Max Industry assignments would result in target RP/PP ratio of %.2f ( %.1f / %.1f )" % (
            ctRP0 / (ctPP0 + 0.0001), ctRP0, ctPP0)
        print "-------------------------------------"
        print "%34s|%20s|%15s |%15s|%15s |%15s " % (
            "                      Planet ", " current RP/PP ",
            " current target RP/PP ", "current Focus ", "  newFocus ",
            " new target RP/PP ")
        totalChanged = 0
        for id_set in empirePlanetIDs, preset_ids:
            for pid in id_set:
                canFocus = planetMap[pid].currentMeterValue(
                    fo.meterType.targetPopulation) > 0
                oldFocus = currentFocus[pid]
                newFocus = newFoci.get(pid, IFocus)
                cPP, cRP = currentOutput[pid][IFocus], currentOutput[pid][
                    RFocus]
                otPP, otRP = newTargets[pid].get(oldFocus, (0, 0))
                ntPP, ntRP = otPP, otRP
                if newFocus != oldFocus and newFocus in planetMap[
                        pid].availableFoci:  # planetMap[pid].focus
                    totalChanged += 1
                    if newFocus != planetMap[pid].focus:
                        result = fo.issueChangeFocusOrder(pid, newFocus)
                        if result == 1:
                            ntPP, ntRP = newTargets[pid].get(newFocus, (0, 0))
                        else:
                            print "Trouble changing focus of planet %s (%d) to %s" % (
                                planetMap[pid].name, pid, newFocus)
                print "pID (%3d) %22s | c: %5.1f / %5.1f | cT: %5.1f / %5.1f |  cF: %8s | nF: %8s | cT: %5.1f / %5.1f " % (
                    pid, planetMap[pid].name, cRP, cPP, otRP, otPP,
                    fociMap.get(oldFocus,
                                'unknown'), fociMap[newFocus], ntRP, ntPP)
            print "-------------------------------------"
        print "-------------------------------------"
        print "Final Ratio Target (turn %4d) RP/PP : %.2f ( %.1f / %.1f ) after %d Focus changes" % (
            fo.currentTurn(), curTargetRP /
            (curTargetPP + 0.0001), curTargetRP, curTargetPP, totalChanged)
        resource_timer.end()
    aPP, aRP = empire.productionPoints, empire.resourceProduction(
        fo.resourceType.research)
    # Next string used in charts. Don't modify it!
    print "Current Output (turn %4d) RP/PP : %.2f ( %.1f / %.1f )" % (
        fo.currentTurn(), aRP / (aPP + 0.0001), aRP, aPP)
    print "------------------------"
    print "ResourcesAI Time Requirements:"
Example #19
0
def setPlanetResourceFoci():
    "set resource focus of planets except capitalID, asteroids, and gas giants"
    global __timerFile

    print "\n============================"
    print "Collecting info to assess Planet Focus Changes\n"
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    currentTurn = fo.currentTurn()
    freq = (1.0 + currentTurn/4.0)**(1.0/3)
    if random() > 1.0/freq:
        timer = 6*[time()]
    else:
        timer= [ time() ] # getPlanets
        empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
        timer.append( time() ) #filter
        timer.append( time() ) #Priority
        #TODO: take into acct splintering of resource groups
        #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)
        ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION)
        rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH)
        priorityRatio = float(rpPrio)/(ppPrio+0.0001)
        timer.append( time() ) # shuffle
        # not supporting Growth for general planets until also adding code to make sure would actually benefit
        #shuffle(generalPlanetIDs)
        timer.append( time() ) # targets
        pp, rp = getResourceTargetTotals()
        planets = map(universe.getPlanet,  empirePlanetIDs)
        planetMap = dict(  zip( empirePlanetIDs,  planets)) 
        print "\n-----------------------------------------"
        print "Making Planet Focus Change Determinations\n"
        
        ratios = []
        #for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that
        # include a bias to slightly discourage changing foci
        curTargetPP = 0
        curTargetRP = 0
        newFoci = {}
        timer.append( time() ) #loop
        hasForce = empire.getTechStatus("CON_FRC_ENRG_STRC") == fo.techStatus.complete
        for pid in newTargets:
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            if currentFocus[pid] == MFocus:
                II = max( II,  newTargets[pid][MFocus][0] ) 
            curTargetPP += II  #icurTargets initially calculated by Industry focus, which will be our default focus
            curTargetRP += IR
            newFoci[pid] = IFocus
            if foAI.foAIstate.aggression < 4:
                if currentFocus[pid] in [ IFocus,  MFocus] :
                    II += min( 2,  II /4.0 )
                elif currentFocus[pid] == RFocus:
                    RR += min( 2,  RR/4.0 )
                #calculate factor F at  which     II + F * RI  ==  RI + F * RR   =====>  F = ( II-RI ) / (RR-IR)
            thisFactor = ( II-RI ) / max( 0.01,  RR-IR)  # don't let denominator be zero for planets where focus doesn't change RP
            if foAI.foAIstate.aggression >3:
                if currentOutput[pid][ IFocus] > II +RI - RR:
                    thisFactor = min(thisFactor,  1.0 + thisFactor/10.0 ) 
            ratios.append( (thisFactor,  pid ) )
                
        ctPP0 = curTargetPP
        ctRP0 = curTargetRP 
        ratios.sort()
        printedHeader=False
        fociMap={IFocus:"Industry",  RFocus:"Research", MFocus:"Mining",  GFocus:"Growth"}
        gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete
        for ratio,  pid in ratios:
            if priorityRatio < ( curTargetRP/ (curTargetPP + 0.0001)) : #we have enough RP
                if ratio < 1.1  and foAI.foAIstate.aggression >1 :  #but wait, RP is still super cheap relative to PP, maybe will take more RP
                    if priorityRatio < 1.5* ( curTargetRP/ (curTargetPP + 0.0001)) : #yeah, really a glut of RP, stop taking RP
                        break
                else: #RP not super cheap & we have enough, stop taking it
                    break
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            if currentFocus[pid] == MFocus:
                II = max( II,  newTargets[pid][MFocus][0] ) 
            if gotAlgo and (
                   (ratio > 2.0 and curTargetPP < 15) or   
                   (ratio > 2.5 and curTargetPP < 25  and II > 5) or 
                   (ratio > 3.0 and curTargetPP < 40  and II > 5) or 
                   (ratio > 4.0 and curTargetPP < 100  and II > 10)  or
                   (  (curTargetRP+RR-IR)/max(0.001,  curTargetPP - II+RI) > 2*  priorityRatio  )):  # we already have algo elegance and more RP would be too expensive, or overkill
                        if not printedHeader:
                            printedHeader=True
                            print "Rejecting further Research Focus choices  as too expensive:"
                            print "%34s|%20s|%15s |%15s|%15s |%15s |%15s"%("                      Planet  ", " current RP/PP ", " current target RP/PP ", "current Focus ","  rejectedFocus  ", " rejected target RP/PP ",  "rejected RP-PP EQF")
                        oldFocus=currentFocus[pid]
                        cPP, cRP = currentOutput[pid][IFocus],  currentOutput[pid][RFocus]
                        otPP, otRP= newTargets[pid].get(oldFocus,  (0, 0))
                        ntPP, ntRP= newTargets[pid].get(RFocus,  (0, 0))
                        print "pID (%3d)  %22s |  c:  %5.1f / %5.1f |   cT:  %5.1f / %5.1f  |  cF: %8s |  nF: %8s  | cT:  %5.1f / %5.1f |         %.2f"%(pid,  planetMap[pid].name, cRP, cPP,   otRP, otPP,  fociMap.get(oldFocus, 'unknown'),  fociMap[RFocus] , ntRP, ntPP , ratio)
                        continue  # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose
            newFoci[pid] = RFocus
            curTargetRP += (RR-IR)
            curTargetPP -= (II-RI)
        print "============================"
        print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f  ( %.1f / %.1f )"%(priorityRatio,  rp/(pp+0.0001),  rp,  pp)
        print "Max Industry assignments would result in target RP/PP ratio of %.2f  ( %.1f / %.1f )"%( ctRP0/ (ctPP0 + 0.0001), ctRP0,  ctPP0 )
        print "-------------------------------------"
        print "%34s|%20s|%15s |%15s|%15s |%15s "%("                      Planet  ", " current RP/PP ", " current target RP/PP ", "current Focus ","  newFocus  ", " new target RP/PP ")
        totalChanged=0
        for pid in newTargets:
            oldFocus=currentFocus[pid]
            changeFocus=False
            newFocus = newFoci[pid]
            cPP, cRP = currentOutput[pid][IFocus],  currentOutput[pid][RFocus]
            if newFocus==RFocus and oldFocus!=RFocus:
                changeFocus = True
            elif newFocus == IFocus:
                if  ( MFocus in planetMap[pid].availableFoci )  and ( newTargets[pid].setdefault(MFocus,  (25, IR))[0] > newTargets[pid][IFocus][0]):
                    newFocus=MFocus
                if newFocus !=oldFocus:
                    changeFocus = True
            else:
                pass #not supporting growth focus yet
            if changeFocus:
                totalChanged+=1
                fo.issueChangeFocusOrder(pid, newFocus)
            otPP, otRP= newTargets[pid].get(oldFocus,  (0, 0))
            ntPP, ntRP= newTargets[pid].get(newFocus,  (0, 0))
            print "pID (%3d)  %22s |  c:  %5.1f / %5.1f |   cT:  %5.1f / %5.1f  |  cF: %8s |  nF: %8s  | cT:  %5.1f / %5.1f "%(pid,  planetMap[pid].name, cRP, cPP,   otRP, otPP,  fociMap.get(oldFocus, 'unknown'),  fociMap[newFocus] , ntRP, ntPP )
        print "-------------------------------------\nFinal Ratio Target (turn %4d) RP/PP : %.2f  ( %.1f / %.1f )  after %d Focus changes"%( fo.currentTurn(), curTargetRP/ (curTargetPP + 0.0001), curTargetRP,  curTargetPP ,  totalChanged)
        
    aPP, aRP = empire.productionPoints,  empire.resourceProduction(fo.resourceType.research)
    print "Current Output (turn %4d) RP/PP : %.2f  ( %.1f / %.1f )"%(fo.currentTurn(),  aRP/ (aPP + 0.0001), aRP,  aPP ), "\n------------------------"
    
    timer.append( time() ) #end
    if doResourceTiming and __timerEntries==__timerEntries2:
        times = [timer[i] - timer[i-1] for i in range(1,  len(timer) ) ]
        timeFmt = "%30s: %8d msec  "
        print "ResourcesAI Time Requirements:"
        for mod,  modTime in zip(__timerEntries,  times):
            print timeFmt%((30*' '+mod)[-30:],  int(1000*modTime))
        if resourceTimerFile:
            print "len times: %d  ;  len entries: %d "%(len(times),  len(__timerEntries))
            resourceTimerFile.write(  __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x),  times )) +'\n')
            resourceTimerFile.flush()
Example #20
0
def setPlanetResourceFoci(): #+
    "set resource focus of planets "
    global __timerFile

    print "\n============================"
    print "Collecting info to assess Planet Focus Changes\n"
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    currentTurn = fo.currentTurn()
    freq = min(3,  ( max(5,  currentTurn-120)   )/4.0)**(1.0/3) 
    if  ( abs(currentTurn - lastFociCheck[0] ) <1.5*freq)   and ( random() < 1.0/freq ) :
        timer = 6*[time()]
    else:
        lastFociCheck[0]=currentTurn
        timer= [ time() ] # getPlanets
        empirePlanetIDs = list( PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) )
        timer.append( time() ) #filter
        timer.append( time() ) #Priority
        #TODO: take into acct splintering of resource groups
        #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)
        ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION)
        rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH)
        priorityRatio = float(rpPrio)/(ppPrio+0.0001)
        timer.append( time() ) # shuffle
        # not supporting Growth for general planets until also adding code to make sure would actually benefit
        #shuffle(generalPlanetIDs)
        timer.append( time() ) # targets
        planets = map(universe.getPlanet,  empirePlanetIDs)
        planetMap = dict(  zip( empirePlanetIDs,  planets)) 
        if useGrowth:
            for metab,  metabIncPop in ColonisationAI.empireMetabolisms.items():
                for special in [aspec for aspec in AIDependencies.metabolimBoostMap.get(metab,  []) if aspec in ColonisationAI.availableGrowthSpecials]:
                    rankedPlanets=[]
                    for pid in ColonisationAI.availableGrowthSpecials[special]:
                        planet = planetMap[pid]
                        pop = planet.currentMeterValue(fo.meterType.population)
                        if (pop > metabIncPop - planet.size) or (GFocus not in planet.availableFoci): #not enough benefit to lose local production, or can't put growth focus here
                            continue
                        for special2 in [ "COMPUTRONIUM_SPECIAL"  ]:
                            if special2 in planet.specials:
                                break
                        else: #didn't have any specials that would override interest in growth special
                            print "Considering  Growth Focus for %s (%d) with special %s; planet has pop %.1f and %s metabolism incremental pop is %.1f"%(
                                                                                                                                                          planet.name,  pid,  special,  pop,  metab,  metabIncPop)
                            rankedPlanets.append(  (pop,  pid) )
                    if rankedPlanets == []:
                        continue
                    rankedPlanets.sort()
                    print "Considering  Growth Focus choice for  special %s; possible planet pop,  id pairs are %s"%(metab,  rankedPlanets)
                    for spSize,  spPID in rankedPlanets: #index 0 should be able to set focus, but just in case...
                        result = 1
                        curFocus = planet.focus
                        if curFocus != GFocus:
                            result = fo.issueChangeFocusOrder(spPID, GFocus)
                        if result == 1:
                            if spPID in empirePlanetIDs:
                                del empirePlanetIDs[   empirePlanetIDs.index( spPID ) ]
                            print "%s focus of planet %s (%d) at Growth Focus"%( ["set",  "left" ][  curFocus == GFocus ] ,  planetMap[spPID].name,  spPID) 
                            break
                        else:
                            print "failed setting focus of planet %s (%d) at Growth Focus; focus left at %s"%(  planetMap[spPID].name,  spPID,  planetMap[spPID].focus) 
        pp, rp = getResourceTargetTotals(empirePlanetIDs,  planetMap)
        print "\n-----------------------------------------"
        print "Making Planet Focus Change Determinations\n"
        
        ratios = []
        #for each planet, calculate RP:PP value ratio at which industry/Mining focus and research focus would have the same total value, & sort by that
        # include a bias to slightly discourage changing foci
        curTargetPP = 0.001
        curTargetRP = 0.001
        newFoci = {}
        timer.append( time() ) #loop
        hasForce = empire.getTechStatus("CON_FRC_ENRG_STRC") == fo.techStatus.complete
        for pid in newTargets:
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            CI, CR = currentOutput[pid][ IFocus],  currentOutput[pid][ RFocus]
            #consider straddling balance range within which 1RP costs 1PP
            if True and (foAI.foAIstate.aggression >= fo.aggression.aggressive):
                if (CR<RR) and ( (CR-IR) >= (II-CI) ) and (priorityRatio > ( (curTargetRP+CR+1)/ max(0.001, curTargetPP +CI -1))):
                    curTargetPP += CI -1 #
                    curTargetRP +=  CR+1
                    newFoci[pid] = RFocus
                    continue
            curTargetPP += II  #icurTargets initially calculated by Industry focus, which will be our default focus
            curTargetRP += IR
            newFoci[pid] = IFocus
            #if foAI.foAIstate.aggression < fo.aggression.maniacal:
            #    if currentFocus[pid] in [ IFocus,  MFocus] :
            #        II += min( 2,  II /4.0 )
            #    elif currentFocus[pid] == RFocus:
            #        RR += min( 2,  RR/4.0 )
            #calculate factor F at  which     II + F * RI  ==  RI + F * RR   =====>  F = ( II-RI ) / (RR-IR)
            thisFactor = ( II-RI ) / max( 0.01,  RR-IR)  # don't let denominator be zero for planets where focus doesn't change RP
            if foAI.foAIstate.aggression >fo.aggression.aggressive:
                if currentOutput[pid][ IFocus] > II +RI - RR:
                    thisFactor = min(thisFactor,  1.0 + thisFactor/10.0 ) 
            ratios.append( (thisFactor,  pid ) )
                
        ctPP0 = curTargetPP
        ctRP0 = curTargetRP 
        ratios.sort()
        printedHeader=False
        fociMap={IFocus:"Industry",  RFocus:"Research", MFocus:"Mining",  GFocus:"Growth"}
        gotAlgo = empire.getTechStatus("LRN_ALGO_ELEGANCE") == fo.techStatus.complete
        for ratio,  pid in ratios:
            if priorityRatio < ( curTargetRP/ (curTargetPP + 0.0001)) : #we have enough RP
                if ratio < 1.1  and foAI.foAIstate.aggression >fo.aggression.cautious :  #but wait, RP is still super cheap relative to PP, maybe will take more RP
                    if priorityRatio < 1.5* ( curTargetRP/ (curTargetPP + 0.0001)) : #yeah, really a glut of RP, stop taking RP
                        break
                else: #RP not super cheap & we have enough, stop taking it
                    break
            II, IR = newTargets[pid][IFocus]
            RI, RR = newTargets[pid][RFocus]
            #if currentFocus[pid] == MFocus:
            #    II = max( II,  newTargets[pid][MFocus][0] ) 
            if gotAlgo and (
                   (ratio > 2.0 and curTargetPP < 15) or   
                   (ratio > 2.5 and curTargetPP < 25  and II > 5) or 
                   (ratio > 3.0 and curTargetPP < 40  and II > 5) or 
                   (ratio > 4.0 and curTargetPP < 100  and II > 10)  or
                   (  (curTargetRP+RR-IR)/max(0.001,  curTargetPP - II+RI) > 2*  priorityRatio  )):  # we already have algo elegance and more RP would be too expensive, or overkill
                        if not printedHeader:
                            printedHeader=True
                            print "Rejecting further Research Focus choices  as too expensive:"
                            print "%34s|%20s|%15s |%15s|%15s |%15s |%15s"%("                      Planet  ", " current RP/PP ", " current target RP/PP ", "current Focus ","  rejectedFocus  ", " rejected target RP/PP ",  "rejected RP-PP EQF")
                        oldFocus=currentFocus[pid]
                        cPP, cRP = currentOutput[pid][IFocus],  currentOutput[pid][RFocus]
                        otPP, otRP= newTargets[pid].get(oldFocus,  (0, 0))
                        ntPP, ntRP= newTargets[pid].get(RFocus,  (0, 0))
                        print "pID (%3d)  %22s |  c:  %5.1f / %5.1f |   cT:  %5.1f / %5.1f  |  cF: %8s |  nF: %8s  | cT:  %5.1f / %5.1f |         %.2f"%(pid,  planetMap[pid].name, cRP, cPP,   otRP, otPP,  fociMap.get(oldFocus, 'unknown'),  fociMap[RFocus] , ntRP, ntPP , ratio)
                        continue  # RP is getting too expensive, but might be willing to still allocate from a planet with less PP to lose
            if planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0: #only set to research if  pop won't die out
                newFoci[pid] = RFocus
                curTargetRP += (RR-IR)
                curTargetPP -= (II-RI)
        print "============================"
        print "Planet Focus Assignments to achieve target RP/PP ratio of %.2f from current ratio of %.2f  ( %.1f / %.1f )"%(priorityRatio,  rp/(pp+0.0001),  rp,  pp)
        print "Max Industry assignments would result in target RP/PP ratio of %.2f  ( %.1f / %.1f )"%( ctRP0/ (ctPP0 + 0.0001), ctRP0,  ctPP0 )
        print "-------------------------------------"
        print "%34s|%20s|%15s |%15s|%15s |%15s "%("                      Planet  ", " current RP/PP ", " current target RP/PP ", "current Focus ","  newFocus  ", " new target RP/PP ")
        totalChanged=0
        for pid in newTargets:
            canFocus= planetMap[pid].currentMeterValue(fo.meterType.targetPopulation) >0
            oldFocus=currentFocus[pid]
            newFocus = newFoci[pid]
            cPP, cRP = currentOutput[pid][IFocus],  currentOutput[pid][RFocus]
            if newFocus!= planetMap[pid].focus and newFocus in planetMap[pid].availableFoci:
                totalChanged+=1
                result = fo.issueChangeFocusOrder(pid, newFocus)
                if result != 1:
                    print "Trouble changing focus of planet %s (%d) to %s"%(planetMap[pid].name,  pid,  newFocus)
            otPP, otRP= newTargets[pid].get(oldFocus,  (0, 0))
            ntPP, ntRP= newTargets[pid].get(newFocus,  (0, 0))
            print "pID (%3d)  %22s |  c:  %5.1f / %5.1f |   cT:  %5.1f / %5.1f  |  cF: %8s |  nF: %8s  | cT:  %5.1f / %5.1f "%(pid,  planetMap[pid].name, cRP, cPP,   otRP, otPP,  fociMap.get(oldFocus, 'unknown'),  fociMap[newFocus] , ntRP, ntPP )
        print "-------------------------------------\nFinal Ratio Target (turn %4d) RP/PP : %.2f  ( %.1f / %.1f )  after %d Focus changes"%( fo.currentTurn(), curTargetRP/ (curTargetPP + 0.0001), curTargetRP,  curTargetPP ,  totalChanged)
        
    aPP, aRP = empire.productionPoints,  empire.resourceProduction(fo.resourceType.research)
    print "Current Output (turn %4d) RP/PP : %.2f  ( %.1f / %.1f )"%(fo.currentTurn(),  aRP/ (aPP + 0.0001), aRP,  aPP ), "\n------------------------"
    
    timer.append( time() ) #end
    if doResourceTiming and __timerEntries==__timerEntries2:
        times = [timer[i] - timer[i-1] for i in range(1,  len(timer) ) ]
        timeFmt = "%30s: %8d msec  "
        print "ResourcesAI Time Requirements:"
        for mod,  modTime in zip(__timerEntries,  times):
            print timeFmt%((30*' '+mod)[-30:],  int(1000*modTime))
        if resourceTimerFile:
            print "len times: %d  ;  len entries: %d "%(len(times),  len(__timerEntries))
            resourceTimerFile.write(  __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x),  times )) +'\n')
            resourceTimerFile.flush()
Example #21
0
def setGeneralPlanetResourceFocus():
    "set resource focus of planets except capitalID, asteroids, and gas giants"
    global __timerFile

    universe = fo.getUniverse()
    empire = fo.getEmpire()
    empireID = empire.empireID
    timer= [ time() ] # getPlanets
    empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID)
    timer.append( time() ) #filter
    capitalIDL = [PlanetUtilsAI.getCapital()]
    asteroids = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.asteroids)
    gasGiants = PlanetUtilsAI.getTypePlanetEmpireOwned(fo.planetType.gasGiant)
    generalPlanetIDs = list(set(empirePlanetIDs) - (set(capitalIDL)|set(asteroids)|set(gasGiants)))
    timer.append( time() ) #Priority
    #fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
    #fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs)
    ppPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_PRODUCTION)
    rpPrio = foAI.foAIstate.getPriority(AIPriorityType.PRIORITY_RESOURCE_RESEARCH)
    priorityRatio = float(ppPrio)/(rpPrio+0.0001)
    timer.append( time() ) # shuffle
    # not supporting Growth for general planets until also adding code to make sure would actually benefit
    shuffle(generalPlanetIDs)
    timer.append( time() ) # targets
    pp, rp = getResourceTargetTotals()
    targetRatio = pp/(rp+0.0001)
    nplanets = len(generalPlanetIDs)
    nChanges = int(  (  nplanets *  max( 1.0/(rp+0.001),  2.0/(pp+0.0001))  *  ( (pp - rp* priorityRatio)/(priorityRatio +2)))  +0.5 ) # weird formula I came up with to estimate desired number of changes
    print "current target totals -- pp: %.1f   rp: %.1f   ; ratio %.2f  ; desired ratio %.2f  will change up to %d  foci from total of %d planets"%(pp, rp, targetRatio,  priorityRatio,  nChanges,  nplanets)
    timer.append( time() ) #loop
    iChanges = 0
    for planetID in generalPlanetIDs:
        if iChanges >= nChanges: break
        planet = universe.getPlanet(planetID)
        oldFocus=planet.focus
        targetRatio = pp/(rp + 0.0001)
        ratioRatio = priorityRatio / ( targetRatio + 0.0001)
        if  (AIFocusType.FOCUS_MINING in planet.availableFoci): #and ((priorityRatio > 0.5 ) or ( ratioRatio > 0.9  ) ) :  #could be a more complex decision here, 
            if oldFocus != AIFocusType.FOCUS_MINING:
                iChanges +=1 #even if not necessarily  directed towards desired ratio
                fo.issueChangeFocusOrder(planetID, AIFocusType.FOCUS_MINING)
                print "Changing planet focus for ID %s : %s  from %s to %s "%(planetID,  planet.name,  oldFocus,   AIFocusType.FOCUS_MINING )
            continue
        newFocus=None
        if ( ratioRatio > 1.1 ): #needs industry
            if oldFocus == AIFocusType.FOCUS_INDUSTRY:
                continue
            else:
                newFocus = AIFocusType.FOCUS_INDUSTRY
        elif ( ratioRatio < 0.91 ):
            if oldFocus == AIFocusType.FOCUS_RESEARCH:
                continue
            else:
                newFocus = AIFocusType.FOCUS_RESEARCH
        if newFocus:
            #pp -= planet.currentMeterValue(fo.meterType.targetIndustry)
            #rp -= planet.currentMeterValue(fo.meterType.targetResearch)
            fo.issueChangeFocusOrder(planetID, newFocus)
            iChanges += 1
            #pp += planet.currentMeterValue(fo.meterType.targetIndustry)
            #rp += planet.currentMeterValue(fo.meterType.targetResearch)
            print "Changing planet focus for ID %s : %s  from %s to %s "%(planetID,  planet.name,  oldFocus,   newFocus )
    timer.append( time() ) #end
    if doResourceTiming and __timerEntries==__timerEntries2:
        times = [timer[i] - timer[i-1] for i in range(1,  len(timer) ) ]
        timeFmt = "%30s: %8d msec  "
        print "ResourcesAI Time Requirements:"
        for mod,  modTime in zip(__timerEntries,  times):
            print timeFmt%((30*' '+mod)[-30:],  int(1000*modTime))
        if resourceTimerFile:
            print "len times: %d  ;  len entries: %d "%(len(times),  len(__timerEntries))
            resourceTimerFile.write(  __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x),  times )) +'\n')
            resourceTimerFile.flush()