def generateOrders(): print ("Genearting Orders") universe = fo.getUniverse() empire = fo.getEmpire() planetID = empire.capitalID planet = universe.getPlanet(planetID) print "EmpireID: " + str(empire.empireID) + " Name: " + empire.name + " Turn: " + str(fo.currentTurn()) print "CapitalID: " + str(planetID) + " Name: " + planet.name + " Species: " + planet.speciesName # turn cleanup splitFleet() identifyShipDesigns() identifyFleetsRoles() foAIstate.clean(ExplorationAI.getHomeSystemID(), FleetUtilsAI.getEmpireFleetIDs()) # ...missions # ...demands/priorities print("Calling AI Modules") # call AI modules PriorityAI.calculatePriorities() ExplorationAI.assignScoutsToExploreSystems() ColonisationAI.assignColonyFleetsToColonise() InvasionAI.assignInvasionFleetsToInvade() MilitaryAI.assignMilitaryFleetsToSystems() FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions() FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions() ResearchAI.generateResearchOrders() ProductionAI.generateProductionOrders() ResourcesAI.generateResourcesOrders() foAIstate.afterTurnCleanup() fo.doneTurn()
def generateOrders(): global lastTurnTimestamp universe = fo.getUniverse() turnStartTime=time() #starting AI timer here, to be sure AI doesn't get blame for any lags in server being able to provide the Universe object empire = fo.getEmpire() planetID = PlanetUtilsAI.getCapital() planet=None if planetID is not None: planet = universe.getPlanet(planetID) print "***************************************************************************" print "***************************************************************************" print ("Generating Orders") print "EmpireID: " + str(empire.empireID) + " Name: " + empire.name+ "_"+str(empire.empireID-1) +"_pid:"+str(fo.playerID())+"_"+fo.playerName()+"_"+aggressions.get(foAIstate.aggression, "?") + " Turn: " + str(fo.currentTurn()) empireColor=empire.colour print "EmpireColors: %d %d %d %d"%(empireColor.r, empireColor.g, empireColor.b, empireColor.a) if planet: print "CapitalID: " + str(planetID) + " Name: " + planet.name + " Species: " + planet.speciesName else: print "CapitalID: None Currently Name: None Species: None " print "***************************************************************************" print "***************************************************************************" if fo.currentTurn() == 1: declareWarOnAll() # turn cleanup !!! this was formerly done at start of every turn -- not sure why splitNewFleets() #updateShipDesigns() #should not be needed anymore; #updateFleetsRoles() foAIstate.clean() #checks exploration border & clears roles/missions of missing fleets & updates fleet locs foAIstate.reportSystemThreats() # ...missions # ...demands/priorities print("Calling AI Modules") # call AI modules timer=[time()] try: PriorityAI.calculatePriorities() except: print "Error: exception triggered and caught: ", traceback.format_exc() # try traceback.print_exc() timer.append( time() ) try: ExplorationAI.assignScoutsToExploreSystems() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ColonisationAI.assignColonyFleetsToColonise() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: InvasionAI.assignInvasionFleetsToInvade() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: MilitaryAI.assignMilitaryFleetsToSystems() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ResearchAI.generateResearchOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ProductionAI.generateProductionOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ResourcesAI.generateResourcesOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: foAIstate.afterTurnCleanup() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] turnEndTime=time() timeFmt = "%30s: %8d msec " print "AI Module Time Requirements:" for mod, modTime in zip(__timerEntries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if __timerFile: __timerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') __timerFile.flush() if __timerBucketFile: __timerBucketFile.write( __timerBucketFileFmt%tuple( [ fo.currentTurn(), (turnStartTime-lastTurnTimestamp)*1000, (turnEndTime-turnStartTime)*1000 ]) +'\n') __timerBucketFile.flush() lastTurnTimestamp = time() try: fo.doneTurn() except: print "Error: exception triggered and caught: ", traceback.format_exc()
def issueAIFleetOrders(self): "issues AIFleetOrders which can be issued in system and moves to next one if is possible" # TODO: priority ordersCompleted = True print "--------------" print "Checking orders for fleet %d (on turn %d)"%(self.target_id, fo.currentTurn()) print "\t Full Orders are:" for aiFleetOrder2 in self.getAIFleetOrders(): print "\t\t %s"%aiFleetOrder2 print "/t/t------" if EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION in self.getAIMissionTypes(): self.check_retarget_invasion() for aiFleetOrder in self.getAIFleetOrders(): print " checking Order: %s"%(aiFleetOrder) clearAll=False if aiFleetOrder.getAIFleetOrderType() in [ EnumsAI.AIFleetOrderType.ORDER_COLONISE, EnumsAI.AIFleetOrderType.ORDER_OUTPOST, EnumsAI.AIFleetOrderType.ORDER_INVADE]:#TODO: invasion? if self.check_abort_mission(aiFleetOrder): return self.checkMergers(context=str(aiFleetOrder)) if aiFleetOrder.canIssueOrder(verbose=True): #print " " + str(aiFleetOrder) currently already printed in canIssueOrder() if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE and ordersCompleted: #only move if all other orders completed aiFleetOrder.issueOrder() elif aiFleetOrder.getAIFleetOrderType() not in [ EnumsAI.AIFleetOrderType.ORDER_MOVE, EnumsAI.AIFleetOrderType.ORDER_DEFEND]: aiFleetOrder.issueOrder() if not aiFleetOrder.isExecutionCompleted(): ordersCompleted = False else: #check that we're not held up by a Big Monster if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE: thisSysID = aiFleetOrder.getTargetAITarget().target_id thisStatus = foAI.foAIstate.systemStatus.setdefault(thisSysID, {}) if ( thisStatus.get('monsterThreat', 0) > fo.currentTurn() * ProductionAI.curBestMilShipRating()/4.0 ) : if ( ( (self.getAIMissionTypes() + [-1] )[0] not in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE, ]) or ( aiFleetOrder != self.getAIFleetOrders()[-1] ) # if this move order is not this mil fleet's final destination, and blocked by Big Monster, release and hope for more effective reassignment ): print "Aborting mission due to being blocked by Big Monster at system %d , threat %d"%(thisSysID, foAI.foAIstate.systemStatus[thisSysID]['monsterThreat']) print "Full set of orders were:" for aiFleetOrder2 in self.getAIFleetOrders(): print "\t\t %s"%aiFleetOrder2 self.clearAIFleetOrders() self.clearAITargets(([-1]+ self.getAIMissionTypes()[:1])[-1]) return # moving to another system stops issuing all orders in system where fleet is # move order is also the last order in system if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE: fleet = fo.getUniverse().getFleet( self.target_id) if fleet.systemID != aiFleetOrder.getTargetAITarget().target_id: break else: #went through entire order list if ordersCompleted: orders=self.getAIFleetOrders() lastOrder= orders and orders[-1] universe=fo.getUniverse() if orders and lastOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_COLONISE: planet = universe.getPlanet(lastOrder.getTargetAITarget().target_id) system = universe.getSystem(planet.systemID) sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, fo.empireID())).get(fo.visibility.partial, -9999) planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.id, fo.empireID())).get(fo.visibility.partial, -9999) pop=planet.currentMeterValue(fo.meterType.population) if (planetPartialVisTurn == sysPartialVisTurn) and pop==0: print "Potential Error: Fleet %d has tentatively completed its colonize mission but will wait to confirm population."%(self.target_id) print " Order details are %s"%lastOrder print " Order is valid: %s ; is Executed : %s ; is execution completed: %s "%(lastOrder.isValid(), lastOrder.isExecuted(), lastOrder.isExecutionCompleted()) if not lastOrder.isValid(): sourceT = lastOrder.getSourceAITarget() targT = lastOrder.getTargetAITarget() print " source target validity: %s ; target target validity: %s "%(sourceT.valid, targT.valid) if EnumsAI.AITargetType.TARGET_SHIP == sourceT.target_type: shipID = sourceT.target_id ship = universe.getShip(shipID) if not ship: print "Ship id %d not a valid ship id"%(shipID) print " source target Ship (%d), species %s, can%s colonize"%( shipID, ship.speciesName, ["not", ""][ship.canColonize]) return # colonize order must not have completed yet clearAll=True last_sys_target = -1 if orders and lastOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MILITARY: last_sys_target = lastOrder.getTargetAITarget().target_id # if (AIFleetMissionType.FLEET_MISSION_SECURE in self.getAIMissionTypes()) or # not doing this until decide a way to release from a SECURE mission secure_targets = set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs) if (last_sys_target in secure_targets) : #consider a secure mission secureType="Unidentified" if (last_sys_target in AIstate.colonyTargetedSystemIDs): secureType = "Colony" elif last_sys_target in AIstate.outpostTargetedSystemIDs : secureType = "Outpost" elif last_sys_target in AIstate.invasionTargetedSystemIDs : secureType = "Invasion" elif last_sys_target in AIstate.blockadeTargetedSystemIDs : secureType = "Blockade" print "Fleet %d has completed initial stage of its mission to secure system %d (targeted for %s), may release a portion of ships"%(self.target_id, last_sys_target, secureType) clearAll=False fleetID=self.target_id fleet=universe.getFleet(fleetID) if fleet.systemID != -1: loc = fleet.systemID else: loc=fleet.nextSystemID if clearAll: if orders: print "Fleet %d has completed its mission; clearing all orders and targets." % self.target_id print "Full set of orders were:" for aiFleetOrder2 in orders: print "\t\t %s"%aiFleetOrder2 self.clearAIFleetOrders() self.clearAITargets(([-1]+ self.getAIMissionTypes()[:1])[-1]) if foAI.foAIstate.getFleetRole(fleetID) in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE ]: allocations = MilitaryAI.getMilitaryFleets(milFleetIDs=[fleetID], tryReset=False, thisround="Fleet %d Reassignment"%fleetID) if allocations: MilitaryAI.assignMilitaryFleetsToSystems(useFleetIDList=[fleetID], allocations=allocations) else: #no orders print "No Current Orders" else: #TODO: evaluate releasing a smaller portion or none of the ships sysStatus = foAI.foAIstate.systemStatus.setdefault(last_sys_target, {}) newFleets=[] threat_present = (sysStatus.get('totalThreat', 0) != 0) or (sysStatus.get('neighborThreat', 0) != 0) target_system = universe.getSystem(last_sys_target) if (not threat_present) and target_system: for pid in target_system.planetIDs: planet = universe.getPlanet(pid) if planet and (planet.owner != fo.empireID()) and (planet.currentMeterValue(fo.meterType.maxDefense) > 0): threat_present = True break if not threat_present: print "No current threat in target system; releasing a portion of ships." newFleets=FleetUtilsAI.splitFleet(self.target_id) #at least first stage of current task is done; release extra ships for potential other deployments else: print "Threat remains in target system; NOT releasing any ships." newMilFleets = [] for fleetID in newFleets: if foAI.foAIstate.getFleetRole(fleetID) in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE ]: newMilFleets.append(fleetID) allocations=[] if newMilFleets: allocations = MilitaryAI.getMilitaryFleets(milFleetIDs=newMilFleets, tryReset=False, thisround="Fleet Reassignment %s"%newMilFleets) if allocations: MilitaryAI.assignMilitaryFleetsToSystems(useFleetIDList=newMilFleets, allocations=allocations)
def issueAIFleetOrders(self): "issues AIFleetOrders which can be issued in system and moves to next one if is possible" # TODO: priority ordersCompleted = True print "Checking orders for fleet %d"%(self.getAITargetID()) #print "\t Full Orders are:" #for aiFleetOrder2 in self.getAIFleetOrders(): # print "\t\t %s"%aiFleetOrder2 for aiFleetOrder in self.getAIFleetOrders(): print " %s"%(aiFleetOrder) clearAll=False if aiFleetOrder.getAIFleetOrderType() in [EnumsAI.AIFleetOrderType.ORDER_COLONISE, EnumsAI.AIFleetOrderType.ORDER_OUTPOST]:#TODO: invasion? universe=fo.getUniverse() planet = universe.getPlanet(aiFleetOrder.getTargetAITarget().getTargetID()) if not planet: clearAll =True elif aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_COLONISE : if ( (planet.currentMeterValue(fo.meterType.population) >0) or not ( planet.unowned or planet.ownedBy(fo.empireID()) ) ) : clearAll =True elif not planet.unowned: clearAll =True if clearAll: print "Fleet %d had a target planet that is no longer valid for this mission; aborting."%(self.getAITargetID() ) self.clearAIFleetOrders() self.clearAITargets(([-1]+ self.getAIMissionTypes()[:1])[-1]) FleetUtilsAI.splitFleet(self.getAITargetID() ) return self.checkMergers(context=str(aiFleetOrder)) if aiFleetOrder.canIssueOrder(verbose=True): #print " " + str(aiFleetOrder) currently already printed in canIssueOrder() if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE and ordersCompleted: #only move if all other orders completed aiFleetOrder.issueOrder() elif aiFleetOrder.getAIFleetOrderType() not in [ EnumsAI.AIFleetOrderType.ORDER_MOVE, EnumsAI.AIFleetOrderType.ORDER_DEFEND]: aiFleetOrder.issueOrder() if not aiFleetOrder.isExecutionCompleted(): ordersCompleted = False else: #check that we're not held up by a Big Monster if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE: thisSysID = aiFleetOrder.getTargetAITarget().getTargetID() thisStatus = foAI.foAIstate.systemStatus.setdefault(thisSysID, {}) if ( thisStatus.get('monsterThreat', 0) > fo.currentTurn() * ProductionAI.curBestMilShipRating()/4.0 ) : if ( ( (self.getAIMissionTypes() + [-1] )[0] not in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE, ]) or ( aiFleetOrder != self.getAIFleetOrders()[-1] ) # if this move order is not this mil fleet's final destination, and blocked by Big Monster, release and hope for more effective reassignment ): print "Aborting mission due to being blocked by Big Monster at system %d , threat %d"%(thisSysID, foAI.foAIstate.systemStatus[thisSysID]['monsterThreat']) print "Full set of orders were:" for aiFleetOrder2 in self.getAIFleetOrders(): print "\t\t %s"%aiFleetOrder2 self.clearAIFleetOrders() self.clearAITargets(([-1]+ self.getAIMissionTypes()[:1])[-1]) return # moving to another system stops issuing all orders in system where fleet is # move order is also the last order in system if aiFleetOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MOVE: fleet = fo.getUniverse().getFleet( self.getAITargetID() ) if fleet.systemID != aiFleetOrder.getTargetAITarget().getTargetID(): break else: #went through entire order list if ordersCompleted: orders=self.getAIFleetOrders() lastOrder= orders and orders[-1] universe=fo.getUniverse() if orders and lastOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_COLONISE: planet = universe.getPlanet(lastOrder.getTargetAITarget().getTargetID()) pop=planet.currentMeterValue(fo.meterType.population) if pop==0: print "Fleet %d has tentatively completed its colonize mission but will wait to confirm population."%(self.getAITargetID() ) print " Order details are %s"%lastOrder print " Order is valid: %s ; is Executed : %s ; is execution completed: %s "%(lastOrder.isValid(), lastOrder.isExecuted(), lastOrder.isExecutionCompleted()) if not lastOrder.isValid(): sourceT = lastOrder.getSourceAITarget() targT = lastOrder.getTargetAITarget() print " source target validity: %s ; target target validity: %s "%(sourceT.isValid() , targT.isValid()) if EnumsAI.AITargetType.TARGET_SHIP == sourceT: shipID = sourceT.getTargetID() ship = universe.getShip(shipID) if not ship: print "Ship id %d not a valid ship id"%(shipID) print " source target Ship (%d), species %s, can%s colonize"%( shipID, ship.speciesName, ["not", ""][ship.canColonize]) return # colonize order must not have completed yet clearAll=True if orders and lastOrder.getAIFleetOrderType() == EnumsAI.AIFleetOrderType.ORDER_MILITARY: # if (AIFleetMissionType.FLEET_MISSION_SECURE in self.getAIMissionTypes()) or # not doing this until decide a way to release from a SECURE mission if (lastOrder.getTargetAITarget().getTargetID() in list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs))): #consider a secure mission print "Fleet %d has completed initial stage of its mission to secure system %d, may release a portion of ships"%(self.getAITargetID() , lastOrder.getTargetAITarget().getTargetID()) clearAll=False fleetID=self.getAITargetID() fleet=universe.getFleet(fleetID) if fleet.systemID != -1: loc = fleet.systemID else: loc=fleet.nextSystemID if clearAll: print "Fleet %d has completed its mission; clearing all orders and targets."%(self.getAITargetID() ) print "Full set of orders were:" for aiFleetOrder2 in self.getAIFleetOrders(): print "\t\t %s"%aiFleetOrder2 self.clearAIFleetOrders() self.clearAITargets(([-1]+ self.getAIMissionTypes()[:1])[-1]) if foAI.foAIstate.getFleetRole(fleetID) in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE ]: allocations = MilitaryAI.getMilitaryFleets(milFleetIDs=[fleetID], tryReset=False, round="Fleet %d Reassignment"%fleetID) if allocations: MilitaryAI.assignMilitaryFleetsToSystems(useFleetIDList=[fleetID], allocations=allocations) else: #TODO: evaluate releasing a smaller portion or none of the ships newFleets=FleetUtilsAI.splitFleet(self.getAITargetID() ) #at least first stage of current task is done; release extra ships for potential other deployments newMilFleets = [] for fleetID in newFleets: if foAI.foAIstate.getFleetRole(fleetID) in [ EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK, EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, EnumsAI.AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE ]: newMilFleets.append(fleetID) allocations = MilitaryAI.getMilitaryFleets(milFleetIDs=newMilFleets, tryReset=False, round="Fleet Reassignment %s"%newMilFleets) if allocations: MilitaryAI.assignMilitaryFleetsToSystems(useFleetIDList=newMilFleets, allocations=allocations)