From: <dil...@us...> - 2013-10-19 07:21:00
|
Revision: 6455 http://sourceforge.net/p/freeorion/code/6455 Author: dilvish-fo Date: 2013-10-19 07:20:55 +0000 (Sat, 19 Oct 2013) Log Message: ----------- improved some AI invasion capability, other misc AI adjustments Modified Paths: -------------- trunk/FreeOrion/default/AI/AIFleetMission.py trunk/FreeOrion/default/AI/AIFleetOrder.py trunk/FreeOrion/default/AI/AIstate.py trunk/FreeOrion/default/AI/ColonisationAI.py trunk/FreeOrion/default/AI/ExplorationAI.py trunk/FreeOrion/default/AI/FleetUtilsAI.py trunk/FreeOrion/default/AI/FreeOrionAI.py trunk/FreeOrion/default/AI/InvasionAI.py trunk/FreeOrion/default/AI/MilitaryAI.py trunk/FreeOrion/default/AI/MoveUtilsAI.py trunk/FreeOrion/default/AI/PlanetUtilsAI.py trunk/FreeOrion/default/AI/PriorityAI.py trunk/FreeOrion/default/AI/ProductionAI.py trunk/FreeOrion/default/AI/ResearchAI.py trunk/FreeOrion/default/AI/TechsListsAI.py Modified: trunk/FreeOrion/default/AI/AIFleetMission.py =================================================================== --- trunk/FreeOrion/default/AI/AIFleetMission.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/AIFleetMission.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -15,6 +15,9 @@ AIFleetMissionTypeNames = EnumsAI.AIFleetMissionType() AIShipRoleTypeNames = EnumsAI.AIShipRoleType() +def dictFromMap(thismap): + return dict( [ (el.key(), el.data() ) for el in thismap ] ) + class AIFleetMission(AIAbstractMission.AIAbstractMission): ''' Stores information about AI mission. Every mission has fleetID and AI targets depending upon AI fleet mission type. @@ -320,16 +323,19 @@ 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 pop==0: - print "Fleet %d has tentatively completed its colonize mission but will wait to confirm population."%(self.target_id) + 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: + if EnumsAI.AITargetType.TARGET_SHIP == sourceT.target_type: shipID = sourceT.target_id ship = universe.getShip(shipID) if not ship: @@ -341,8 +347,8 @@ 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 - if (last_sys_target in list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + - AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs))): #consider 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" Modified: trunk/FreeOrion/default/AI/AIFleetOrder.py =================================================================== --- trunk/FreeOrion/default/AI/AIFleetOrder.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/AIFleetOrder.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -8,6 +8,9 @@ dumpTurn=0 +def dictFromMap(thismap): + return dict( [ (el.key(), el.data() ) for el in thismap ] ) + class AIFleetOrder(object): "Stores information about orders which can be executed" @@ -75,7 +78,10 @@ # colonise planet if AITargetType.TARGET_PLANET == self.getTargetAITarget().target_type: planet = universe.getPlanet(self.getTargetAITarget().target_id) - if planet.unowned: + 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) + if (planetPartialVisTurn == sysPartialVisTurn) and planet.unowned: targetAITargetTypeValid = True else:#try to get order cancelled out self.__setExecuted() @@ -96,7 +102,11 @@ # colonise planet if AITargetType.TARGET_PLANET == self.getTargetAITarget().target_type: planet = universe.getPlanet(self.getTargetAITarget().target_id) - if planet.unowned or (planet.ownedBy(fo.empireID()) and planet.currentMeterValue(fo.meterType.population)==0 ): + 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) + + if (planetPartialVisTurn == sysPartialVisTurn) and ( planet.unowned or (planet.ownedBy(fo.empireID()) and planet.currentMeterValue(fo.meterType.population)==0 )): targetAITargetTypeValid = True else:#try to get order cancelled out self.__setExecuted() @@ -297,6 +307,8 @@ return False systemID = fleet.systemID + if systemID == targetID: + return True #already there so no point to worry about threat sys1=universe.getSystem(systemID) sys1Name = (sys1 and sys1.name) or "unknown" targ1 = universe.getSystem(targetID) Modified: trunk/FreeOrion/default/AI/AIstate.py =================================================================== --- trunk/FreeOrion/default/AI/AIstate.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/AIstate.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -76,8 +76,8 @@ self.empireID = empire.empireID self.origHomeworldID = empire.capitalID homeworld = universe.getPlanet(self.origHomeworldID) - self.origSpeciesName = homeworld.speciesName - self.origHomeSystemID = homeworld.systemID + self.origSpeciesName = (homeworld and homeworld.speciesName) or "" + self.origHomeSystemID = (homeworld and homeworld.systemID) or -1 self.visBorderSystemIDs = {self.origHomeSystemID:1} self.visInteriorSystemIDs= {} self.expBorderSystemIDs = {self.origHomeSystemID:1} @@ -94,8 +94,15 @@ self.misc={} self.qualifyingColonyBaseTargets={} self.qualifyingOutpostBaseTargets={} + self.qualifyingTroopBaseTargets={} + + def __setstate__(self, state_dict): + self.__dict__.update(state_dict) # update attributes + for dict_attrib in ['qualifyingColonyBaseTargets', 'qualifyingOutpostBaseTargets', 'qualifyingTroopBaseTargets']: + if dict_attrib not in state_dict: + self.__dict__[dict_attrib] = {} - def __del__(self): + def __del__(self): #TODO: confirm if anything about bosst interface really requires this "destructor" del self.__shipRoleByDesignID del self.__fleetRoleByID @@ -108,6 +115,7 @@ del self.misc del self.qualifyingColonyBaseTargets del self.qualifyingOutpostBaseTargets + del self.qualifyingTroopBaseTargets def clean(self): "turn start AIstate cleanup" @@ -601,7 +609,14 @@ estats = enemygroup[1] if estats == {}: attack_tally += count * sum([ a * b for a, b in myattacks.items()]) - structure_tally += count * (mystructure + myshields * 3*sum(myattacks.values())) #uses num of my attacks for proxy calc of structure help from shield + attack_total = sum( [num * max(0, a_key - myshields) for a_key, num in myattacks.items()] ) + attack_net = max(sum( [num * max(0, a_key - myshields) for a_key, num in myattacks.items()] ), 0.1 * attack_total) #TODO: reconsider capping at 10-fold boost + #attack_diff = attack_total - attack_net + if attack_net > 0: #will be unless no attacks at all, due to above calc + shield_boost = mystructure * (attack_tally / attack_net) + else: + shield_boost = 0 + structure_tally += count * (mystructure + shield_boost) #uses num of my attacks for proxy calc of structure help from shield total_enemy_weights += count continue eshields = estats.get('shields', 0) @@ -609,7 +624,16 @@ tempstruc = max(1e-4, estats.get('structure', 1)) thisweight = count * tempstruc total_enemy_weights += thisweight - structure_tally += thisweight * max(mystructure, min(estats.get('attacks', {})) - myshields ) # + e_attacks = estats.get('attacks', {}) + #structure_tally += thisweight * max(mystructure, min(e_attacks) - myshields ) #TODO: improve shielded attack calc + attack_total = sum( [num * max(0, a_key - myshields) for a_key, num in e_attacks.items()] ) + attack_net = max(sum( [num * max(0, a_key - myshields) for a_key, num in e_attacks.items()] ), 0.1 * attack_total) #TODO: reconsider approach + #attack_diff = attack_total - attack_net + if attack_net > 0: #will be unless no attacks at all, due to above calc + shield_boost = mystructure * (attack_tally / attack_net) + else: + shield_boost = 0 + structure_tally += thisweight * (mystructure + shield_boost) for attack, nattacks in myattacks: adjustedattack = max(0, attack-eshields) thisattack = min(tempstruc, nattacks*adjustedattack) @@ -631,6 +655,7 @@ elif designID in self.designStats: return self.designStats[designID] design = fo.getShipDesign(designID) + detect_bonus = 0 if design: attacks = {} for attack in list(design.directFireStats): @@ -647,7 +672,15 @@ shields = 7 elif "SH_DEFENSE_GRID" in parts: shields = 4 - stats = {'attack':design.attack, 'structure':design.structure, 'shields':shields, 'attacks':attacks} + if "DT_DETECTOR_4" in parts: + detect_bonus = 4 + elif "DT_DETECTOR_3" in parts: + detect_bonus = 3 + elif "DT_DETECTOR_2" in parts: + detect_bonus = 2 + elif "DT_DETECTOR_1" in parts: + detect_bonus = 1 + stats = {'attack':design.attack, 'structure':(design.structure + detect_bonus), 'shields':shields, 'attacks':attacks} else: stats = {'attack':0, 'structure':0, 'shields':0, 'attacks':{}} self.designStats[designID] = stats @@ -747,6 +780,7 @@ ResourcesAI.lastFociCheck[0]=0 self.qualifyingColonyBaseTargets.clear() self.qualifyingOutpostBaseTargets.clear() + self.qualifyingTroopBaseTargets.clear() #self.reset_invasions() def reset_invasions(self): Modified: trunk/FreeOrion/default/AI/ColonisationAI.py =================================================================== --- trunk/FreeOrion/default/AI/ColonisationAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/ColonisationAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -62,6 +62,7 @@ def dictFromMap(this_map): return dict( [ (el.key(), el.data() ) for el in this_map ] ) + def resetCAIGlobals(): global curBestMilShipRating empireSpecies.clear() @@ -399,8 +400,6 @@ #foAI.foAIstate.qualifyingColonyBaseTargets.clear() cost_ratio = 120 #TODO: temp ratio; reest to 12 *; consider different ratio for pid in evaluatedColonyPlanetIDs: #TODO: reorganize - if pid in foAI.foAIstate.qualifyingOutpostBaseTargets: - continue planet = universe.getPlanet(pid) if not planet: continue @@ -409,12 +408,12 @@ planet2 = universe.getPlanet(pid2) if not planet2: continue - if planet2.speciesName in empireColonizers: + if (pid not in foAI.foAIstate.qualifyingOutpostBaseTargets) and (planet2.speciesName in empireColonizers): + if (pid not in empireOutpostIDs): + foAI.foAIstate.qualifyingOutpostBaseTargets.setdefault(pid, [pid2, -1]) + if (pid not in foAI.foAIstate.qualifyingColonyBaseTargets) and (planet2.speciesName in empireColonizers): if colonyCost < cost_ratio * availPP_BySys.get(sysID, 0): foAI.foAIstate.qualifyingColonyBaseTargets.setdefault(pid, [pid2, -1])#TODO: check other local colonizers for better score - if (pid not in empireOutpostIDs): - foAI.foAIstate.qualifyingOutpostBaseTargets.setdefault(pid, [pid2, -1]) - break # print "Evaluated Colony PlanetIDs: " + str(evaluatedColonyPlanetIDs) @@ -635,6 +634,14 @@ return 0 detail.append("%s : "%planet.name ) system = universe.getSystem(planet.systemID) + + sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, empire.empireID)).get(fo.visibility.partial, -9999) + planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planetID, empire.empireID)).get(fo.visibility.partial, -9999) + + if planetPartialVisTurn < sysPartialVisTurn: + print "Colonization AI couldn't get current info on planet id %d (was stealthed at last sighting)"%planetID + return 0 #last time we had partial vis of the system, the planet was stealthed to us #TODO: track detection strength, order new scouting when it goes up + tagList=[] starBonus=0 colonyStarBonus=0 @@ -839,7 +846,7 @@ gotAsteroids=False gotOwnedAsteroids = False - gotGG = False + got_GG = False gotOwnedGG = False if system and AIFocusType.FOCUS_INDUSTRY in species.foci: for pid in [temp_id for temp_id in system.planetIDs if temp_id != planetID]: @@ -850,7 +857,7 @@ if p2.owner != -1: gotOwnedAsteroids = True if p2.size== fo.planetSize.gasGiant: - gotGG = True + got_GG = True if p2.owner != -1: gotOwnedGG = True if gotAsteroids: @@ -865,7 +872,7 @@ if species and species.canProduceShips: asteroidBonus += 30*discountMultiplier*pilotVal detail.append( "Asteroid ShipBuilding from %s %.1f"%(p2.name, discountMultiplier*20*pilotVal ) ) - if gotGG: + if got_GG: if ( (empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete ) or ( "PRO_ORBITAL_GEN" in empireResearchList[:3]) ): if gotOwnedGG: flat_industry += perGGG #will go into detailed industry projection @@ -1009,13 +1016,14 @@ empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() homeworld = universe.getPlanet(capitalID) + distanceFactor = 0 if homeworld: homeSystemID = homeworld.systemID evalSystemID = planet.systemID - leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) - distanceFactor = 1.001 / (leastJumpsPath + 1) - else: - distanceFactor = 0 + if (homeSystemID != -1) and (evalSystemID != -1): + leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) + #leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) + distanceFactor = 1.001 / (leastJumpsPath + 1) for special in [ spec for spec in planetSpecials if spec in AIDependencies.metabolimBoosts]: gbonus = discountMultiplier * basePopInd * indMult * empireMetabolisms.get( AIDependencies.metabolimBoosts[special] , 0)# due to growth applicability to other planets @@ -1111,10 +1119,11 @@ if rating[0]>bestScore: bestScore = rating[0] targetID = pid - foAI.foAIstate.qualifyingOutpostBaseTargets[targetID][1] = -1 #TODO: should probably delete - aiTarget = AITarget.AITarget(AITargetType.TARGET_PLANET, targetID) - aiFleetMission = foAI.foAIstate.getAIFleetMission(fid) - aiFleetMission.addAITarget(AIFleetMissionType.FLEET_MISSION_ORBITAL_OUTPOST, aiTarget) + if targetID != -1: + foAI.foAIstate.qualifyingOutpostBaseTargets[targetID][1] = -1 #TODO: should probably delete + aiTarget = AITarget.AITarget(AITargetType.TARGET_PLANET, targetID) + aiFleetMission = foAI.foAIstate.getAIFleetMission(fid) + aiFleetMission.addAITarget(AIFleetMissionType.FLEET_MISSION_ORBITAL_OUTPOST, aiTarget) # assign fleet targets to colonisable planets sendColonyShips(AIstate.colonyFleetIDs, foAI.foAIstate.colonisablePlanetIDs, AIFleetMissionType.FLEET_MISSION_COLONISATION) Modified: trunk/FreeOrion/default/AI/ExplorationAI.py =================================================================== --- trunk/FreeOrion/default/AI/ExplorationAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/ExplorationAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -49,7 +49,7 @@ # order fleets to explore #explorableSystemIDs = foAI.foAIstate.getExplorableSystems(AIExplorableSystemType.EXPLORABLE_SYSTEM_UNEXPLORED) explorableSystemIDs = list(borderUnexploredSystemIDs) - if not explorableSystemIDs: + if not explorableSystemIDs or (capitalSysID == -1): return expSystemsByDist = sorted( map( lambda x: ( universe.linearDistance(capitalSysID, x), x) , explorableSystemIDs ) ) print "Exploration system considering following system-distance pairs:\n %s"%("[ "+ ", ".join(["%3d : %5.1f"%(sys, dist) for dist, sys in expSystemsByDist]) +" ]") Modified: trunk/FreeOrion/default/AI/FleetUtilsAI.py =================================================================== --- trunk/FreeOrion/default/AI/FleetUtilsAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/FleetUtilsAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -313,10 +313,10 @@ selectedRole= AIFleetMissionType.FLEET_MISSION_OUTPOST elif AIShipRoleType.SHIP_ROLE_BASE_OUTPOST in shipRoles: selectedRole= AIFleetMissionType.FLEET_MISSION_ORBITAL_OUTPOST + elif AIShipRoleType.SHIP_ROLE_BASE_INVASION in shipRoles: + selectedRole= AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION elif AIShipRoleType.SHIP_ROLE_BASE_DEFENSE in shipRoles: selectedRole= AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE - elif AIShipRoleType.SHIP_ROLE_BASE_INVASION in shipRoles: - selectedRole= AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION elif AIShipRoleType.SHIP_ROLE_MILITARY_INVASION in shipRoles: selectedRole= AIFleetMissionType.FLEET_MISSION_INVASION #### @@ -402,6 +402,7 @@ print "Military Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY)) print "Orbital Defense Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE)) print "Outpost Base Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_ORBITAL_OUTPOST)) + print "Invasion Base Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION)) print "Securing Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_SECURE)) + " (currently FLEET_MISSION_MILITARY should be used instead of this Role)" print "Unclassifyable Fleets : " + str(getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVALID)) @@ -453,6 +454,14 @@ for invasionAIFleetMission in invasionAIFleetMissions: print " " + str(invasionAIFleetMission) + troopBaseAIFleetMissions = foAI.foAIstate.getAIFleetMissionsWithAnyMissionTypes([AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION]) + if len( troopBaseAIFleetMissions) >0: + print "Invasion Base targets (must have been interrupted by combat): " + else: + print "Invasion Base targets: None (as expected, due to expected timing of order submission and execution)" + for invasionAIFleetMission in troopBaseAIFleetMissions: + print " " + str(invasionAIFleetMission) + militaryAIFleetMissions = foAI.foAIstate.getAIFleetMissionsWithAnyMissionTypes([AIFleetMissionType.FLEET_MISSION_MILITARY]) if len( militaryAIFleetMissions) >0: print "General Military targets: " Modified: trunk/FreeOrion/default/AI/FreeOrionAI.py =================================================================== --- trunk/FreeOrion/default/AI/FreeOrionAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/FreeOrionAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -72,7 +72,7 @@ planet_id = PlanetUtilsAI.getCapital() planet = None universe = fo.getUniverse() - if planet_id is not None: + if planet_id is not None and planet_id != -1: planet = universe.getPlanet(planet_id) new_name = random.choice(_capitols.get(aggression, [""]).split('\n')).strip() + " " + planet.name print "Capitol City Names are: ", _capitols Modified: trunk/FreeOrion/default/AI/InvasionAI.py =================================================================== --- trunk/FreeOrion/default/AI/InvasionAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/InvasionAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -48,7 +48,10 @@ visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() visiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(visibleSystemIDs) - accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] + if homeSystemID != -1: + accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if (sysID != -1 ) and universe.systemsConnected(sysID, homeSystemID, empireID) ] + else: + accessibleSystemIDs = [] #TODO: check if any troop ships still owned, use their system as home system acessiblePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(accessibleSystemIDs) #allOwnedPlanetIDs = PlanetUtilsAI.getAllOwnedPlanetIDs(exploredPlanetIDs) @@ -67,10 +70,9 @@ print "" print "Current Invasion Targeted SystemIDs: " + str(PlanetUtilsAI.sysNameIDs(AIstate.invasionTargetedSystemIDs)) invasionTargetedPlanetIDs = getInvasionTargetedPlanetIDs(universe.planetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, empireID) - allInvasionTargetedSystemIDs = PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs) + invasionTargetedPlanetIDs.extend( getInvasionTargetedPlanetIDs(universe.planetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, empireID)) + allInvasionTargetedSystemIDs = set(PlanetUtilsAI.getSystems(invasionTargetedPlanetIDs)) - # export invasion targeted systems for other AI modules - AIstate.invasionTargetedSystemIDs = allInvasionTargetedSystemIDs print "Current Invasion Targeted PlanetIDs: " + str(PlanetUtilsAI.planetNameIDs(invasionTargetedPlanetIDs)) invasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) @@ -81,8 +83,73 @@ numInvasionFleets = len(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(invasionFleetIDs)) print "Invasion Fleets Without Missions: " + str(numInvasionFleets) + + availablePP = {} + for el in empire.planetsWithAvailablePP: #keys are sets of ints; data is doubles + avail_pp = el.data() + for pid in el.key(): + availablePP[pid] = avail_pp + if len (invadablePlanetIDs) > 0: + #print "Evaluating Troop Bases (SpaceInvaders) for %s"%(invadablePlanetIDs) + pass + for pid in invadablePlanetIDs: #TODO: reorganize + planet = universe.getPlanet(pid) + if not planet: + continue + sysID = planet.systemID + sysPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(planet.systemID, empireID)).get(fo.visibility.partial, -9999) + planetPartialVisTurn = dictFromMap(universe.getVisibilityTurnsMap(pid, empireID)).get(fo.visibility.partial, -9999) + if (planetPartialVisTurn < sysPartialVisTurn): + #print "rejecting %s due to stealth"%planet.name + continue + for pid2 in ColonisationAI.empireSpeciesSystems.get(sysID, {}).get('pids', []): + if availablePP.get(pid2, 0) < 2: #TODO: improve troop base PP sufficiency determination + #print "rejecting %s due to insufficient avail PP"%planet.name + break + planet2 = universe.getPlanet(pid2) + if not planet2: + continue + if (pid not in foAI.foAIstate.qualifyingTroopBaseTargets) and (planet2.speciesName in ColonisationAI.empireShipBuilders): + #print "Adding %s to Troop Bases (SpaceInvaders) potential target list, from %s"%(planet.name, planet2.name) + foAI.foAIstate.qualifyingTroopBaseTargets.setdefault(pid, [pid2, -1]) + break - evaluatedPlanetIDs = list(set(invadablePlanetIDs) - set(invasionTargetedPlanetIDs)) #TODO: check if any invasionTargetedPlanetIDs need more troops assigned + for pid in list(foAI.foAIstate.qualifyingTroopBaseTargets): + planet = universe.getPlanet(pid) + if planet and planet.owner == empireID: + del foAI.foAIstate.qualifyingTroopBaseTargets[pid] + + reserved_troop_base_targets = [] + secureAIFleetMissions = foAI.foAIstate.getAIFleetMissionsWithAnyMissionTypes([EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE]) + #print "considering possible troop bases at %s" % (foAI.foAIstate.qualifyingTroopBaseTargets.keys()) + for pid in (set(foAI.foAIstate.qualifyingTroopBaseTargets.keys()) - set(invasionTargetedPlanetIDs)): #TODO: consider overriding standard invasion mission + planet = universe.getPlanet(pid) + if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1: + reserved_troop_base_targets.append(pid) + if planet: + allInvasionTargetedSystemIDs.add( planet.systemID ) + continue #already building for here + loc = foAI.foAIstate.qualifyingTroopBaseTargets[pid][0] + this_score, p_troops = evaluateInvasionPlanet(pid, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire, secureAIFleetMissions, False) + if (planet.currentMeterValue(fo.meterType.shield)) > 0: + continue + bestShip, colDesign, buildChoices = ProductionAI.getBestShipInfo(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_ORBITAL_INVASION, loc) + if not bestShip: + #print "Error: no troop base can be built at ", PlanetUtilsAI.planetNameIDs([loc]) + continue + #print "selecting ", PlanetUtilsAI.planetNameIDs([loc]), " to build Orbital troop bases" + n_bases = math.ceil((p_troops+1) / 2)#TODO: reconsider this +1 safety factor + retval = fo.issueEnqueueShipProductionOrder(bestShip, loc) + print "Enqueueing %d Troop Bases at %s for %s"%( n_bases, PlanetUtilsAI.planetNameIDs([loc]), PlanetUtilsAI.planetNameIDs([pid])) + if retval !=0: + allInvasionTargetedSystemIDs.add( planet.systemID ) + reserved_troop_base_targets.append(pid) + foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] = loc + fo.issueChangeProductionQuantityOrder(empire.productionQueue.size -1, 1, int(n_bases)) + res=fo.issueRequeueProductionOrder(empire.productionQueue.size -1, 0) + + #TODO: check if any invasionTargetedPlanetIDs need more troops assigned + evaluatedPlanetIDs = list(set(invadablePlanetIDs) - set(invasionTargetedPlanetIDs) - set(reserved_troop_base_targets) ) print "Evaluating potential invasions, PlanetIDs: " + str(evaluatedPlanetIDs) evaluatedPlanets = assignInvasionValues(evaluatedPlanetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire) @@ -108,6 +175,10 @@ AIstate.opponentPlanetIDs = [pid for pid, pscore, trp in sortedPlanets] AIstate.invasionTargets = sortedPlanets + # export invasion targeted systems for other AI modules + AIstate.invasionTargetedSystemIDs = list(allInvasionTargetedSystemIDs) + + def getInvasionTargetedPlanetIDs(planetIDs, missionType, empireID): "return list of being invaded planets" @@ -137,8 +208,8 @@ return planetValues -def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire, secureAIFleetMissions): - "return the invasion value of a planet" +def evaluateInvasionPlanet(planetID, missionType, fleetSupplyablePlanetIDs, empire, secureAIFleetMissions, verbose=True): + "return the invasion value (score, troops) of a planet" detail = [] buildingValues = {"BLD_IMPERIAL_PALACE": 1000, "BLD_CULTURE_ARCHIVES": 1000, @@ -200,8 +271,9 @@ if homeworld: homeSystemID = homeworld.systemID evalSystemID = planet.systemID - leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) - maxJumps = leastJumpsPath + if (homeSystemID != -1) and (evalSystemID != -1): + leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) + maxJumps = leastJumpsPath troops = planet.currentMeterValue(fo.meterType.troops) maxTroops = planet.currentMeterValue(fo.meterType.maxTroops) @@ -228,7 +300,8 @@ sysMThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('monsterThreat', 0 ) sysPThrt = foAI.foAIstate.systemStatus.get(pSysID, {}).get('planetThreat', 0 ) sysTotThrt = sysFThrt + sysMThrt + sysPThrt - print "invasion eval of %s %d --- maxShields %.1f -- sysFleetThreat %.1f -- sysMonsterThreat %.1f"%(planet.name, planetID, pmaxShield, sysFThrt, sysMThrt) + if verbose: + print "invasion eval of %s %d --- maxShields %.1f -- sysFleetThreat %.1f -- sysMonsterThreat %.1f"%(planet.name, planetID, pmaxShield, sysFThrt, sysMThrt) supplyVal=0 enemyVal=0 if planet.owner!=-1 : #value in taking this away from an enemy @@ -312,6 +385,43 @@ def assignInvasionFleetsToInvade(): # assign fleet targets to invadable planets + + universe = fo.getUniverse() + empire = fo.getEmpire() + empireID = empire.empireID + fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs + fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) + + allTroopBaseFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) + availTroopBaseFleetIDs = FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allTroopBaseFleetIDs) + for fid in availTroopBaseFleetIDs: + fleet = universe.getFleet(fid) + if not fleet: + continue + sysID = fleet.systemID + system = universe.getSystem(sysID) + availPlanets = set(system.planetIDs).intersection(set( foAI.foAIstate.qualifyingTroopBaseTargets.keys())) + print "Considering Base Troopers in %s, found planets %s and regtistered targets %s with status %s"%(system.name, list(system.planetIDs), availPlanets, + [(pid, foAI.foAIstate.qualifyingTroopBaseTargets[pid]) for pid in availPlanets]) + targets = [pid for pid in availPlanets if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1 ] + if not targets: + print "Error found no valid target for troop base in system %s (%d)"%(system.name, sysID) + continue + + targetID=-1 + bestScore=-1 + # + for pid, rating in assignInvasionValues(targets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire).items(): + p_score, p_troops = rating + if p_score>bestScore: + bestScore = p_score + targetID = pid + if targetID != -1: + foAI.foAIstate.qualifyingTroopBaseTargets[targetID][1] = -1 #TODO: should probably delete + aiTarget = AITarget.AITarget(EnumsAI.AITargetType.TARGET_PLANET, targetID) + aiFleetMission = foAI.foAIstate.getAIFleetMission(fid) + aiFleetMission.addAITarget(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, aiTarget) + invasionFleetIDs = AIstate.invasionFleetIDs sendInvasionFleets(invasionFleetIDs, AIstate.invasionTargets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) Modified: trunk/FreeOrion/default/AI/MilitaryAI.py =================================================================== --- trunk/FreeOrion/default/AI/MilitaryAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/MilitaryAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -153,6 +153,7 @@ safetyFactor = [ 4.0, 3.0, 1.5, 1.0, 1.0, 0.95 ][foAI.foAIstate.aggression] topTargetPlanets = [pid for pid, pscore, trp in AIstate.invasionTargets[:PriorityAI.allottedInvasionTargets] if pscore > 20] + [pid for pid, pscore in foAI.foAIstate.colonisablePlanetIDs[:10] if pscore > 20] + topTargetPlanets.extend( foAI.foAIstate.qualifyingTroopBaseTargets.keys() ) topTargetSystems = [] for sysID in AIstate.invasionTargetedSystemIDs + PlanetUtilsAI.getSystems( topTargetPlanets ): if sysID not in topTargetSystems: @@ -606,14 +607,15 @@ empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() homeworld = universe.getPlanet(capitalID) + distanceFactor=0 if homeworld: homeSystemID = homeworld.systemID evalSystemID = system.systemID - leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) - distanceFactor = 1.001/(leastJumpsPath + 1) + if (homeSystemID != -1) and (evalSystemID != -1): + leastJumpsPath = len(universe.leastJumpsPath(homeSystemID, evalSystemID, empireID)) + distanceFactor = 1.001/(leastJumpsPath + 1) else: homeSystemID=-1 - distanceFactor=0 if systemID == homeSystemID: return 10 Modified: trunk/FreeOrion/default/AI/MoveUtilsAI.py =================================================================== --- trunk/FreeOrion/default/AI/MoveUtilsAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/MoveUtilsAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -51,7 +51,10 @@ pathFunc=universe.shortestPath startSysID = fromSystemAITarget.target_id targetSysID = toSystemAITarget.target_id - shortPath= list( pathFunc(startSysID, targetSysID, empireID) ) + if (startSysID != -1) and (targetSysID != -1): + shortPath= list( pathFunc(startSysID, targetSysID, empireID) ) + else: + shortPath = [] suppliedStops = [ sid for sid in shortPath if sid in fleetSupplyableSystemIDs ] unsuppliedStops = [sid for sid in shortPath if sid not in suppliedStops ] retPath=[] @@ -119,10 +122,11 @@ minJumps = 9999 # infinity supplySystemID = -1 for systemID in fleetSupplyableSystemIDs: - leastJumpsPath = universe.leastJumpsPath(startSystemID, systemID, empireID) - if len(leastJumpsPath) < minJumps: - minJumps = len(leastJumpsPath) - supplySystemID = systemID + if (startSystemID != -1) and (systemID != -1): + leastJumpsPath = universe.leastJumpsPath(startSystemID, systemID, empireID) + if len(leastJumpsPath) < minJumps: + minJumps = len(leastJumpsPath) + supplySystemID = systemID return AITarget.AITarget(AITargetType.TARGET_SYSTEM, supplySystemID) @@ -134,7 +138,11 @@ newTargets = resultSystemAITargets[:] if fromSystemAITarget.valid and toSystemAITarget.valid and supplySystemAITarget.valid: universe = fo.getUniverse() - leastJumpsPath = universe.leastJumpsPath(fromSystemAITarget.target_id, toSystemAITarget.target_id, empireID) + if (fromSystemAITarget.target_id != -1) and (toSystemAITarget.target_id != -1): + leastJumpsPath = universe.leastJumpsPath(fromSystemAITarget.target_id, toSystemAITarget.target_id, empireID) + else: + leastJumpsPath = [] + result = False fromSystemID = fromSystemAITarget.target_id for systemID in leastJumpsPath: if not fromSystemID == systemID: Modified: trunk/FreeOrion/default/AI/PlanetUtilsAI.py =================================================================== --- trunk/FreeOrion/default/AI/PlanetUtilsAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/PlanetUtilsAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -28,7 +28,7 @@ empire = fo.getEmpire() if empire == None: print "Danger Danger! FO can't find an empire for me!!!!" - return None + return -1 empireID = empire.empireID capitalID = empire.capitalID homeworld = universe.getPlanet(capitalID) @@ -45,7 +45,7 @@ if empireOwnedPlanetIDs: return empireOwnedPlanetIDs[0] else: - return None + return -1 popMap = [] for planetID in peopledPlanets: popMap.append( ( universe.getPlanet(planetID).currentMeterValue(fo.meterType.population) , planetID) ) @@ -54,7 +54,7 @@ def getCapitalSysID(): capID = getCapital() - if capID is None: + if capID is None or capID==-1: return -1 else: return fo.getUniverse().getPlanet(capID).systemID Modified: trunk/FreeOrion/default/AI/PriorityAI.py =================================================================== --- trunk/FreeOrion/default/AI/PriorityAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/PriorityAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -193,7 +193,7 @@ #allottedColonyTargets = 1+ int(fo.currentTurn()/50) allottedColonyTargets = 1 + int( totalPP*turnsToBuild*allottedPortion/colonyCost) - numColonisablePlanetIDs = len( [ pid for (pid, (score, specName) ) in foAI.foAIstate.colonisablePlanetIDs if score > 60 ][:allottedColonyTargets] ) + numColonisablePlanetIDs = len( [ pid for (pid, (score, specName) ) in foAI.foAIstate.colonisablePlanetIDs if score > 60 ][:allottedColonyTargets+2] ) if (numColonisablePlanetIDs == 0): return 1 colonyshipIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION) @@ -299,7 +299,7 @@ empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() - if capitalID: + if capitalID is not None and capitalID != -1: homeworld = universe.getPlanet(capitalID) else: return 0# no capitol (not even a capitol-in-the-making), means can't produce any ships Modified: trunk/FreeOrion/default/AI/ProductionAI.py =================================================================== --- trunk/FreeOrion/default/AI/ProductionAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/ProductionAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -40,11 +40,18 @@ if (fo.currentTurn()+1) in bestMilRatingsHistory: bestMilRatingsHistory.clear() if fo.currentTurn() not in bestMilRatingsHistory: - bestShip, bestDesign, buildChoices = getBestShipInfo( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) + milBuildChoices = getBestShipRatings() + if milBuildChoices == []: + return 0.00001 + top = milBuildChoices[0] + bestDesignID, bestDesign, buildChoices = top[2], top[3], [top[0]] + #bestShip, bestDesign, buildChoices = getBestShipInfo( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY) if bestDesign is None: return 0.00001 # empire cannot currently produce any military ships, don't make zero though, to avoid divide-by-zero - stats = foAI.foAIstate.getDesignIDStats(bestDesign.id) - bestMilRatingsHistory[ fo.currentTurn() ] = stats['attack'] * ( stats['structure'] + stats['shields'] ) + #stats = foAI.foAIstate.getDesignIDStats(bestDesign.id) + stats = foAI.foAIstate.get_weighted_design_stats(bestDesignID, ColonisationAI.empireSpeciesByPlanet.get(buildChoices[0], '')) + foAI.foAIstate.adjust_stats_vs_enemy(stats) + bestMilRatingsHistory[ fo.currentTurn() ] = stats['attack'] * stats['structure'] return bestMilRatingsHistory[ fo.currentTurn() ] def getBestShipInfo(priority, loc=None): @@ -268,6 +275,7 @@ srb3 = "SR_WEAPON_3_%1d" srb4 = "SR_WEAPON_4_%1d" clk = "ST_CLOAK_%1d" + db = "DT_DETECTOR_%1d" if1 = "FU_BASIC_TANK" is1, is2, is3, is4, is5 = "SH_DEFENSE_GRID", "SH_DEFLECTOR", "SH_PLASMA", "SH_MULTISPEC", "SH_BLACK" isList=["", is1, is2, is3, is4, is5] @@ -363,23 +371,32 @@ newMarkDesigns += [ (nb%(4, iw+8), desc, hull, 2*[srb4%iw]+[ar5] + [ is5, if1, if1], "", model) for iw in [2, 3, 4] ] nb, hull = designNameBases[5]+"-%1x-%1x", "SH_HEAVY_ASTEROID" #8 , 9, 10 = "Atlas":"FA", "Pele":"FB", "Xena":"FC" - newMarkDesigns += [ (nb%(1, iw) , desc, hull, [srb%iw] +5*[""] + [if1, if1, if1], "", model) for iw in [2, 3, 4] ] - newMarkDesigns += [ (nb%(2, iw) , desc, hull, [srb2%iw]+5*[""] + [if1, if1, if1], "", model) for iw in [2, 3, 4] ] - newMarkDesigns += [ (nb%(3, iw) , desc, hull, [srb%iw] +3*[""] +2*[ar2]+ [if1, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(4, iw) , desc, hull, [srb2%iw]+3*[""] +2*[ar2]+ [if1, if1, if1], "", model) for iw in [2, 3, 4] ] + newMarkDesigns += [ (nb%(1, iw) , desc, hull, [srb%iw] +4*[""] +[db%1] + [if1, if1, if1], "", model) for iw in [2, 3, 4] ] + newMarkDesigns += [ (nb%(2, iw) , desc, hull, [srb2%iw]+4*[""] +[db%1] + [if1, if1, if1], "", model) for iw in [2, 3, 4] ] + newMarkDesigns += [ (nb%(3, iw) , desc, hull, [srb%iw] +2*[""] +2*[ar2]+[db%2]+ [if1, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(4, iw) , desc, hull, [srb2%iw]+2*[""] +2*[ar2]+[db%1]+ [if1, if1, if1], "", model) for iw in [2, 3, 4] ] + newMarkDesigns += [ (nb%(5, iw) , desc, hull, [srb2%iw]+2*[""] +2*[ar2]+[db%2]+ [if1, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(6, isp ) , desc, hull, [srb2%4] +2*[""] +2*[ar2]+[db%2]+ [isList[isp], if1, if1], "", model) for isp in [1, 2] ] + newMarkDesigns += [ (nb%(7, isp ) , desc, hull, 3*[srb2%4] +2*[ar2] +[db%2]+ [isList[isp], if1, if1], "", model) for isp in [1, 2, 3, 4] ] nb, hull = designNameBases[6]+"-%1x-%1x", "SH_HEAVY_ASTEROID" #8 , 9, 10 = "Atlas":"FA", "Pele":"FB", "Xena":"FC" - newMarkDesigns += [ (nb%(1, iw) , desc, hull, [srb3%iw]+4*[""] +[ar2]+ [if1, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(2, iw) , desc, hull, [srb3%iw]+3*[""] +2*[ar3]+ [if1, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(3, iw) , desc, hull, 3*[srb3%iw]+3*[ar3]+ [is3, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(4, iw) , desc, hull, 4*[srb3%iw]+2*[ar3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(5, iw) , desc, hull, 4*[srb3%iw]+2*[ar4]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(1, iw) , desc, hull, [srb3%iw]+3*[""] +[ar2] + [db%2] + [if1, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(2, iw) , desc, hull, [srb3%iw]+2*[""] +2*[ar3]+ [db%2]+ [if1, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(3, iw) , desc, hull, 3*[srb3%iw]+2*[ar3]+ [db%2]+ [is3, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(4, iw) , desc, hull, 4*[srb3%iw]+1*[ar3]+ [db%2]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(5, iw) , desc, hull, 4*[srb3%iw]+1*[ar3]+ [db%3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(6, iw) , desc, hull, 4*[srb3%iw]+1*[ar4]+ [db%2]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(7, iw) , desc, hull, 4*[srb3%iw]+1*[ar4]+ [db%3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] nb, hull = designNameBases[7]+"-%1x-%1x", "SH_HEAVY_ASTEROID" #8 , 9, 10 = "Atlas":"FA", "Pele":"FB", "Xena":"FC" - newMarkDesigns += [ (nb%(1, iw) , desc, hull, 4*[srb4%iw]+2*[ar3]+ [is3, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(2, iw) , desc, hull, 4*[srb4%iw]+2*[ar4]+ [is3, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(3, iw) , desc, hull, 4*[srb4%iw]+2*[ar3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(4, iw) , desc, hull, 4*[srb4%iw]+2*[ar4]+ [is4, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(5, iw) , desc, hull, 4*[srb4%iw]+2*[ar3]+ [is5, if1, if1], "", model) for iw in [3, 4] ] - newMarkDesigns += [ (nb%(6, iw) , desc, hull, 4*[srb4%iw]+2*[ar4]+ [is5, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(1, iw) , desc, hull, 2*[srb4%iw]+3*[ar2]+ [db%2]+ [is2, if1, if1], "", model) for iw in [1, 2] ] + newMarkDesigns += [ (nb%(2, iw) , desc, hull, 3*[srb4%iw]+2*[ar3]+ [db%2]+ [is3, if1, if1], "", model) for iw in [1, 2] ] + newMarkDesigns += [ (nb%(3, iw) , desc, hull, 2*[srb4%iw]+3*[ar2]+ [db%2]+ [is4, if1, if1], "", model) for iw in [1, 2] ] + newMarkDesigns += [ (nb%(4, iw) , desc, hull, 3*[srb4%iw]+2*[ar3]+ [db%2]+ [is4, if1, if1], "", model) for iw in [1, 2] ] + newMarkDesigns += [ (nb%(5, iw) , desc, hull, 4*[srb4%iw]+1*[ar3]+ [db%3]+ [is3, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(6, iw) , desc, hull, 4*[srb4%iw]+1*[ar4]+ [db%3]+ [is3, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(7, iw) , desc, hull, 4*[srb4%iw]+1*[ar3]+ [db%3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(8, iw) , desc, hull, 4*[srb4%iw]+1*[ar4]+ [db%3]+ [is4, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(9, iw) , desc, hull, 4*[srb4%iw]+1*[ar3]+ [db%3]+ [is5, if1, if1], "", model) for iw in [3, 4] ] + newMarkDesigns += [ (nb%(10, iw) , desc, hull, 4*[srb4%iw]+1*[ar4]+ [db%3]+ [is5, if1, if1], "", model) for iw in [3, 4] ] if False and foAI.foAIstate.aggression >fo.aggression.typical: hull = "SH_SENTIENT" @@ -445,7 +462,7 @@ empire = fo.getEmpire() universe = fo.getUniverse() capitolID = PlanetUtilsAI.getCapital() - if capitolID == None: + if capitolID is None or capitolID == -1: homeworld=None capitolSysID=None else: @@ -500,6 +517,13 @@ movedCapital=False bldgExpense=0.0 bldgRatio = [ 0.4, 0.35, 0.30 ][fo.empireID()%3] + print "Buildings present on all owned planets:" + for pid in list(AIstate.popCtrIDs) + list(AIstate.outpostIDs): + planet = universe.getPlanet(pid) + if planet: + print "%30s: %s"%(planet.name, [universe.getObject(bldg).name for bldg in planet.buildingIDs]) + print + if not homeworld: print "if no capitol, no place to build, should get around to capturing or colonizing a new one"#TODO else: @@ -510,7 +534,7 @@ tags=",".join( thisObj.tags) specials=",".join(thisObj.specials) print "%8s | %20s | type:%20s | tags:%20s | specials: %20s | owner:%d "%(bldg, thisObj.name, "_".join(thisObj.buildingTypeName.split("_")[-2:])[:20], tags, specials, thisObj.owner ) - + print capitalBldgs = [universe.getObject(bldg).buildingTypeName for bldg in homeworld.buildingIDs] #possibleBuildingTypeIDs = [bldTID for bldTID in empire.availableBuildingTypes if fo.getBuildingType(bldTID).canBeProduced(empire.empireID, homeworld.id)] @@ -548,7 +572,7 @@ queuedBldgNames=[ bldg.name for bldg in capitolQueuedBldgs ] if ( totalPP >40 or currentTurn > 40 ) and ("BLD_INDUSTRY_CENTER" in possibleBuildingTypes) and ("BLD_INDUSTRY_CENTER" not in (capitalBldgs+queuedBldgNames)) and (bldgExpense<bldgRatio*totalPP): - res=fo.issueEnqueueBuildingProductionOrder("BLD_INDUSTRY_CENTER", empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder("BLD_INDUSTRY_CENTER", homeworld.id) print "Enqueueing BLD_INDUSTRY_CENTER, with result %d"%res if res: cost, time = empire.productionCostAndTime( productionQueue[productionQueue.size -1] ) @@ -556,7 +580,7 @@ if ("BLD_SHIPYARD_BASE" in possibleBuildingTypes) and ("BLD_SHIPYARD_BASE" not in (capitalBldgs+queuedBldgNames)): try: - res=fo.issueEnqueueBuildingProductionOrder("BLD_SHIPYARD_BASE", empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder("BLD_SHIPYARD_BASE", homeworld.id) print "Enqueueing BLD_SHIPYARD_BASE, with result %d"%res except: print "Error: cant build shipyard at new capital, probably no population; we're hosed" @@ -565,7 +589,7 @@ for bldName in [ "BLD_SHIPYARD_ORG_ORB_INC" ]: if (bldName in possibleBuildingTypes) and (bldName not in (capitalBldgs+queuedBldgNames)) and (bldgExpense<bldgRatio*totalPP): try: - res=fo.issueEnqueueBuildingProductionOrder(bldName, empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder(bldName, homeworld.id) print "Enqueueing %s at capitol, with result %d"%(bldName, res) if res: cost, time = empire.productionCostAndTime( productionQueue[productionQueue.size -1] ) @@ -578,7 +602,7 @@ for bldName in [ "BLD_SHIPYARD_ORG_XENO_FAC", "BLD_SHIPYARD_ORG_CELL_GRO_CHAMB" ]: if ( totalPP >30 or currentTurn > 30 ) and (bldName in possibleBuildingTypes) and (bldName not in (capitalBldgs+queuedBldgNames)) and (bldgExpense<bldgRatio*totalPP): try: - res=fo.issueEnqueueBuildingProductionOrder(bldName, empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder(bldName, homeworld.id) print "Enqueueing %s at capitol, with result %d"%(bldName, res) if res: cost, time = empire.productionCostAndTime( productionQueue[productionQueue.size -1] ) @@ -592,7 +616,7 @@ if ("BLD_EXOBOT_SHIP" in possibleBuildingTypes) and ("BLD_EXOBOT_SHIP" not in queuedBldgNames): if len( ColonisationAI.empireColonizers.get("SP_EXOBOT", []))==0 or numExobotShips==0: #don't have an exobot shipyard yet try: - res=fo.issueEnqueueBuildingProductionOrder("BLD_EXOBOT_SHIP", empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder("BLD_EXOBOT_SHIP", homeworld.id) print "Enqueueing BLD_EXOBOT_SHIP, with result %d"%res if res: res=fo.issueRequeueProductionOrder(productionQueue.size -1, 0) # move to front @@ -601,8 +625,8 @@ print "Error: exception triggered and caught: ", traceback.format_exc() if ("BLD_IMPERIAL_PALACE" in possibleBuildingTypes) and ("BLD_IMPERIAL_PALACE" not in (capitalBldgs+queuedBldgNames)): - res=fo.issueEnqueueBuildingProductionOrder("BLD_IMPERIAL_PALACE", empire.capitalID) - print "Enqueueing BLD_IMPERIAL_PALACE, with result %d"%res + res=fo.issueEnqueueBuildingProductionOrder("BLD_IMPERIAL_PALACE", homeworld.id) + print "Enqueueing BLD_IMPERIAL_PALACE at %s, with result %d"%(homeworld.name, res) if res: res=fo.issueRequeueProductionOrder(productionQueue.size -1, 0) # move to front print "Requeueing BLD_IMPERIAL_PALACE to front of build queue, with result %d"%res @@ -610,7 +634,7 @@ # ok, BLD_NEUTRONIUM_SYNTH is not currently unlockable, but just in case... ;-p if ("BLD_NEUTRONIUM_SYNTH" in possibleBuildingTypes) and ("BLD_NEUTRONIUM_SYNTH" not in (capitalBldgs+queuedBldgNames)): - res=fo.issueEnqueueBuildingProductionOrder("BLD_NEUTRONIUM_SYNTH", empire.capitalID) + res=fo.issueEnqueueBuildingProductionOrder("BLD_NEUTRONIUM_SYNTH", homeworld.id) print "Enqueueing BLD_NEUTRONIUM_SYNTH, with result %d"%res if res: res=fo.issueRequeueProductionOrder(productionQueue.size -1, 0) # move to front @@ -948,6 +972,8 @@ else: distanceMap={} for sysID in best_locs: #want to build close to capitol for defense + if sysID == -1: + continue try: distanceMap[sysID] = len(universe.leastJumpsPath(homeworld.systemID, sysID, empire.empireID)) except: @@ -983,6 +1009,8 @@ else: distanceMap={} for sysID in AIstate.empireStars.get(fo.starType.red, []): + if sysID == -1: + continue try: distanceMap[sysID] = len(universe.leastJumpsPath(homeworld.systemID, sysID, empire.empireID)) except: @@ -1026,6 +1054,8 @@ else: distanceMap={} for sysID in AIstate.empireStars.get(fo.starType.blackHole, []): + if sysID == -1: + continue try: distanceMap[sysID] = len(universe.leastJumpsPath(homeworld.systemID, sysID, empire.empireID)) except: @@ -1098,6 +1128,8 @@ else: distanceMap={} for sysID in AIstate.empireStars.get(fo.starType.neutron, []): + if sysID == -1: + continue try: distanceMap[sysID] = len(universe.leastJumpsPath(homeworld.systemID, sysID, empire.empireID)) except: Modified: trunk/FreeOrion/default/AI/ResearchAI.py =================================================================== --- trunk/FreeOrion/default/AI/ResearchAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/ResearchAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -213,9 +213,9 @@ if ColonisationAI.gotRuins and empire.getTechStatus("LRN_XENOARCH") != fo.techStatus.complete and "LRN_XENOARCH" not in researchQueueList[:4]: if "LRN_ARTIF_MINDS" in researchQueueList: - insert_idx = 5+ researchQueueList.index("LRN_ARTIF_MINDS") + insert_idx = 7+ researchQueueList.index("LRN_ARTIF_MINDS") elif "SPY_DETECT_2" in researchQueueList: - insert_idx = 1+ researchQueueList.index("SPY_DETECT_2") + insert_idx = max(0, researchQueueList.index("SPY_DETECT_2") -2 ) else: insert_idx = 0 for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN" , "LRN_ALGO_ELEGANCE"]: Modified: trunk/FreeOrion/default/AI/TechsListsAI.py =================================================================== --- trunk/FreeOrion/default/AI/TechsListsAI.py 2013-10-18 07:22:47 UTC (rev 6454) +++ trunk/FreeOrion/default/AI/TechsListsAI.py 2013-10-19 07:20:55 UTC (rev 6455) @@ -305,15 +305,18 @@ "SHP_WEAPON_2_2", "SHP_WEAPON_2_3", "SPY_DETECT_2", + "SHP_WEAPON_2_4", "PRO_SENTIENT_AUTOMATION", "DEF_DEFENSE_NET_2", "DEF_DEFENSE_NET_REGEN_1", - "SHP_WEAPON_2_4", "PRO_INDUSTRY_CENTER_II", "SHP_REINFORCED_HULL", "SHP_BASIC_DAM_CONT", "PRO_SOL_ORB_GEN", "GRO_GENETIC_ENG", + "GRO_GENETIC_MED", + "SHP_DEFLECTOR_SHIELD", + "SHP_ADV_DAM_CONT", "DEF_GARRISON_2", "PRO_EXOBOTS", "GRO_XENO_GENETICS", @@ -321,7 +324,6 @@ "CON_METRO_INFRA", "CON_INFRA_ECOL", "GRO_LIFECYCLE_MAN", - "SHP_DEFLECTOR_SHIELD", "SHP_MULTICELL_CAST", "SHP_ENDOCRINE_SYSTEMS", "SHP_ASTEROID_REFORM", @@ -332,7 +334,6 @@ "SHP_WEAPON_3_4", "DEF_PLAN_BARRIER_SHLD_1", "CON_FRC_ENRG_STRC", - "SHP_ADV_DAM_CONT", "LRN_QUANT_NET", "DEF_PLAN_B... [truncated message content] |