From: <dil...@us...> - 2013-03-24 20:48:04
|
Revision: 5903 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5903&view=rev Author: dilvish-fo Date: 2013-03-24 20:47:54 +0000 (Sun, 24 Mar 2013) Log Message: ----------- AI update with improved troopship management & other misc changes Modified Paths: -------------- trunk/FreeOrion/default/AI/AIstate.py trunk/FreeOrion/default/AI/ColonisationAI.py trunk/FreeOrion/default/AI/EnumsAI.py trunk/FreeOrion/default/AI/FleetUtilsAI.py trunk/FreeOrion/default/AI/ProductionAI.py trunk/FreeOrion/default/AI/ResourcesAI.py trunk/FreeOrion/default/AI/charting/charts.py Modified: trunk/FreeOrion/default/AI/AIstate.py =================================================================== --- trunk/FreeOrion/default/AI/AIstate.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/AIstate.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -94,7 +94,7 @@ self.expInteriorSystemIDs= {} self.exploredSystemIDs = {} self.unexploredSystemIDs = {self.origHomeSystemID:1} - self.fleetStatus={} #keys: 'sysID', 'nships' + self.fleetStatus={} #keys: 'sysID', 'nships', 'rating' self.systemStatus={} #keys: 'fleetThreat'. 'planetThreat', 'monsterThreat' (specifically, immobile nonplanet threat), 'myfleets', 'neighbors', 'name', 'myDefenses' self.needsEmergencyExploration=[] self.newlySplitFleets={} Modified: trunk/FreeOrion/default/AI/ColonisationAI.py =================================================================== --- trunk/FreeOrion/default/AI/ColonisationAI.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/ColonisationAI.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -743,21 +743,42 @@ potentialTargets = [ (pid, (score, specName) ) for (pid, (score, specName) ) in evaluatedPlanets if score > (0.8 * cost) ] print "colony/outpost ship matching -- fleets %s to planets %s"%( fleetPool, evaluatedPlanets) - #for planetID_value_pair in evaluatedPlanets: + + #adding a lot of checking here because have been getting mysterious exception, after too many recursions to get info fleetPool=set(fleetPool) universe=fo.getUniverse() + empireID=fo.empireID() + destroyedObjIDs = universe.destroyedObjectIDs(empireID) + for fid in fleetPool: + fleet = universe.getFleet(fid) + if not fleet or fleet.empty: + print "Error: bad fleet ( ID %d ) given to colonization routine; will be skipped"%fid + fleetPool.remove(fid) + continue + reportStr="Fleet ID (%d): %d ships; species: "%(fid, fleet.numShips) + for sid in fleet.shipIDs: + ship = universe.getShip(sid) + if not ship: + reportStr += "NoShip, " + else: + reportStr += "%s, "%ship.speciesName + print reportStr + print + #for planetID_value_pair in evaluatedPlanets: while (len(fleetPool) > 0 ) and ( len(potentialTargets) >0): thisTarget = potentialTargets.pop(0) thisScore=thisTarget[1][0] thisPlanetID=thisTarget[0] - thisSysID = universe.getPlanet(thisPlanetID).systemID + thisPlanet = universe.getPlanet(thisPlanetID) + print "checking pool %s against target %s current owner %s targetSpec %s"%(fleetPool, thisPlanet.name, thisPlanet.owner, thisTarget) + thisSysID = thisPlanet.systemID if (foAI.foAIstate.systemStatus.setdefault(thisSysID, {}).setdefault('monsterThreat', 0) > 2000) or (fo.currentTurn() <20 and foAI.foAIstate.systemStatus[thisSysID]['monsterThreat'] > 200): print "Skipping colonization of system %s due to Big Monster, threat %d"%(PlanetUtilsAI.sysNameIDs([thisSysID]), foAI.foAIstate.systemStatus[thisSysID]['monsterThreat']) continue thisSpec=thisTarget[1][1] foundFleets=[] thisFleetList = FleetUtilsAI.getFleetsForMission(nships=1, targetStats={}, minStats={}, curStats={}, species=thisSpec, systemsToCheck=[thisSysID], systemsChecked=[], - fleetPoolSet = fleetPool, fleetList=foundFleets, verbose=False) + fleetPoolSet = fleetPool, fleetList=foundFleets, triedFleets=set([]), verbose=False) if thisFleetList==[]: fleetPool.update(foundFleets)#just to be safe continue #must have no compatible colony/outpost ships Modified: trunk/FreeOrion/default/AI/EnumsAI.py =================================================================== --- trunk/FreeOrion/default/AI/EnumsAI.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/EnumsAI.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -200,7 +200,7 @@ explorationShip = {"SD_SCOUT":"A", "Scout":"B", "Tracker":"C"} colonyShip = {"SD_COLONY_SHIP":"A", "Seeder":"B", "Nest-Maker":"C", "Den-Maker":"D"} outpostShip = {"SD_OUTPOST_SHIP":"A", "Outposter":"B"} - troopShip = {"SD_TROOP_SHIP":"A", "Basic-Troopers":"B", "Medium-Troopers":"C", "Heavy-Troopers":"D", "Very-Heavy-Troopers":"D"} + troopShip = {"SD_TROOP_SHIP":"A", "Basic-Troopers":"B", "Medium-Troopers":"C", "Heavy-Troopers":"D", "Very-Heavy-Troopers":"E"} attackShip= {"SD_MARK":"A", "Lynx":"B","Griffon":"C", "Wyvern":"D", "Manticore":"E", "Devil":"F", "Reaver":"G", "Obliterator":"H"} colonyBase={"SD_COLONY_BASE":"A", "NestBase":"B"} outpostBase={"SD_OUTPOST_BASE":"A", "OutpostBase":"B"} Modified: trunk/FreeOrion/default/AI/FleetUtilsAI.py =================================================================== --- trunk/FreeOrion/default/AI/FleetUtilsAI.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/FleetUtilsAI.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -42,7 +42,7 @@ return tally def getFleetsForMission(nships, targetStats, minStats, curStats, species, systemsToCheck, systemsChecked, fleetPoolSet, fleetList, - takeAny=False, extendSearch=True, verbose=False): #implements breadth-first search through systems + takeAny=False, extendSearch=True, triedFleets=set([]), verbose=False): #implements breadth-first search through systems if verbose: print "getFleetsForMission: (nships:%1d, targetStats:%s, minStats:%s, curStats:%s, species:%6s, systemsToCheck:%8s, systemsChecked:%8s, fleetPoolSet:%8s, fleetList:%8s) "%( nships, targetStats, minStats, curStats, species, systemsToCheck, systemsChecked, fleetPoolSet, fleetList) @@ -122,7 +122,7 @@ if not fleet.ownedBy(empireID): return [] if len(list(fleet.shipIDs)) <= 1: # fleet with only one ship cannot be split - return [fleetID] + return [] shipIDs = list( fleet.shipIDs ) for shipID in shipIDs[1:]: newFleetID = fo.issueNewFleetOrder("Fleet %d"%(shipID), shipID) @@ -140,7 +140,8 @@ print "Error - got no fleet ID back after trying to split a ship from fleet %d"%fleetID foAI.foAIstate.getFleetRole(fleetID, forceNew=True) # foAI.foAIstate.updateFleetRating(fleetID) # - foAI.foAIstate.ensureHaveFleetMissions(newfleets) + if newfleets !=[]: + foAI.foAIstate.ensureHaveFleetMissions(newfleets) return newfleets def mergeFleetAintoB(fleetA_ID, fleetB_ID, leaveRating=0, needRating=0, context=""): Modified: trunk/FreeOrion/default/AI/ProductionAI.py =================================================================== --- trunk/FreeOrion/default/AI/ProductionAI.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/ProductionAI.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -179,16 +179,16 @@ ar3= "AR_NEUTRONIUM_PLATE" arL=[ar1, ar2, ar3] - for ari in [1, 2]: - nb, hull = designNameBases[ari+2]+"%1d-%1d", "SH_ORGANIC" - #newTroopDesigns += [ (nb%(2, ari+1), desc, hull, ["SR_WEAPON_2", arL[ari], tp, tp], "", model) ] - #newTroopDesigns += [ (nb%(3, ari+1), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp], "", model) ] - nb, hull = designNameBases[ari+2]+"%1d-%1d", "SH_STATIC_MULTICELLULAR" - #newTroopDesigns += [ (nb%(4, ari+1), desc, hull, ["SR_WEAPON_2", arL[ari], tp, tp, tp], "", model) ] - #newTroopDesigns += [ (nb%(5, ari+1), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp, tp], "", model) ] - nb, hull = designNameBases[ari+2]+"%1d-%1d", "SH_ENDOMORPHIC" - newTroopDesigns += [ (nb%(6, ari+1), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp, tp, tp], "", model) ] - newTroopDesigns += [ (nb%(7, ari+1), desc, hull, ["SR_WEAPON_8", arL[ari], tp, tp, tp, tp], "", model) ] + for ari in [1, 2]: #naming below only works because skipping Lead armor + nb, hull = designNameBases[ari+1]+"%1d-%1d", "SH_ORGANIC" + newTroopDesigns += [ (nb%(1, ari), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp], "", model) ] + newTroopDesigns += [ (nb%(2, ari), desc, hull, ["SR_WEAPON_8", arL[ari], tp, tp], "", model) ] + nb, hull = designNameBases[ari+1]+"%1d-%1d", "SH_STATIC_MULTICELLULAR" + newTroopDesigns += [ (nb%(3, ari), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp, tp], "", model) ] + newTroopDesigns += [ (nb%(4, ari), desc, hull, ["SR_WEAPON_8", arL[ari], tp, tp, tp], "", model) ] + nb, hull = designNameBases[ari+1]+"%1d-%1d", "SH_ENDOMORPHIC" + newTroopDesigns += [ (nb%(5, ari), desc, hull, ["SR_WEAPON_5", arL[ari], tp, tp, tp, tp], "", model) ] + newTroopDesigns += [ (nb%(6, ari), desc, hull, ["SR_WEAPON_8", arL[ari], tp, tp, tp, tp], "", model) ] currentTurn=fo.currentTurn() needsAdding=[] @@ -542,8 +542,10 @@ capitolID = PlanetUtilsAI.getCapital() if capitolID == None: homeworld=None + capitolSysID=None else: homeworld = universe.getPlanet(capitolID) + capitolSysID = homeworld.systemID print "Production Queue Management:" empire = fo.getEmpire() productionQueue = empire.productionQueue @@ -1177,6 +1179,33 @@ print "\nFound colony ships in build queue: %s"%queuedColonyShips if queuedOutpostShips: print "\nFound colony ships in build queue: %s"%queuedOutpostShips + + allTroopFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION ) + nTroopTot = sum( [ foAI.foAIstate.fleetStatus.get(fid, {}).get('nships', 0) for fid in allTroopFleetIDs ] ) + availTroopFleetIDs = list( FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allTroopFleetIDs)) + nAvailTroopTot = sum( [ foAI.foAIstate.fleetStatus.get(fid, {}).get('nships', 0) for fid in availTroopFleetIDs ] ) + print "Trooper Status: %d total, with %d unassigned. %d queued"%(nTroopTot, nAvailTroopTot, queuedTroopShips) + if ( capitolID!=None and currentTurn>=40 and foAI.foAIstate.systemStatus.get(capitolSysID, {}).get('fleetThreat', 0)==0 and + foAI.foAIstate.systemStatus.get(capitolSysID, {}).get('neighborThreat', 0)==0): + bestShip, bestDesign, buildChoices = getBestShipInfo( EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_INVASION) + if buildChoices!=None and len(buildChoices)>0: + loc = random.choice(buildChoices) + prodTime = bestDesign.productionTime(empire.empireID, loc) + prodCost=bestDesign.productionCost(empire.empireID, loc) + troopersNeededForcing = max(0, int( 0.99+ (currentTurn/20 - nAvailTroopTot)/max(2, prodTime-1)) ) + numShips=troopersNeededForcing + perTurnCost = (float(prodCost) / prodTime) + if troopersNeededForcing>0 and totalPP > 3*perTurnCost*queuedTroopShips: + retval = fo.issueEnqueueShipProductionOrder(bestShip, loc) + if retval !=0: + print "forcing %d new ship(s) to production queue: %s; per turn production cost %.1f"%(numShips, bestDesign.name(True), numShips*perTurnCost) + print "" + if numShips>1: + fo.issueChangeProductionQuantityOrder(productionQueue.size -1, 1, numShips) + availPP -= numShips*perTurnCost + res=fo.issueRequeueProductionOrder(productionQueue.size -1, 0) # move to front + fo.updateProductionQueue() + print "" print "" # get the highest production priorities Modified: trunk/FreeOrion/default/AI/ResourcesAI.py =================================================================== --- trunk/FreeOrion/default/AI/ResourcesAI.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/ResourcesAI.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -205,20 +205,34 @@ 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: + if pid in empirePlanetIDs: + del empirePlanetIDs[ empirePlanetIDs.index( pid ) ] elif ( ("BLD_CONC_CAMP" in [bld.buildingTypeName for bld in map( universe.getObject, planet.buildingIDs)] ) 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: + if pid in empirePlanetIDs: + del empirePlanetIDs[ empirePlanetIDs.index( pid ) ] pp, rp = getResourceTargetTotals(empirePlanetIDs, planetMap) print "\n-----------------------------------------" @@ -239,7 +253,7 @@ curTargetRP += nRP continue else: - print "Error: new focus %s set early but not applied for planet %s (%d)"%( newFoci[pid], planetMap[pid].name, pid ) + print "Error: new focus %s set early but not applied for planet %s (%d) with species %s"%( newFoci[pid], planetMap[pid].name, pid, planetMap[pid].speciesName ) II, IR = newTargets[pid][IFocus] RI, RR = newTargets[pid][RFocus] CI, CR = currentOutput[pid][ IFocus], currentOutput[pid][ RFocus] Modified: trunk/FreeOrion/default/AI/charting/charts.py =================================================================== --- trunk/FreeOrion/default/AI/charting/charts.py 2013-03-24 14:00:38 UTC (rev 5902) +++ trunk/FreeOrion/default/AI/charting/charts.py 2013-03-24 20:47:54 UTC (rev 5903) @@ -24,8 +24,9 @@ else: return '' +doPlotTypes = ["PP"]#+ [ "RP"] +[ "ShipCount"] -for plotType in ["PP", "RP", "ShipCount"]: +for plotType in doPlotTypes: if plotType=="PP": caption="Production" @@ -69,8 +70,8 @@ data=PP elif plotType=="RP": data=RP - else: - data = shipCount + else: + data = shipCount if data != []: ymin = min(ymin, min(data)) ymax = max(ymax, max(data)) @@ -78,6 +79,13 @@ allData[playerName]=data logfiles=sorted(glob(dataDir+os.sep+"A*.log")) + A1log = glob(dataDir+os.sep+"AI_1.log") + if A1log and A1log[0] in logfiles: + A1Time = os.path.getmtime(A1log[0]) + for path in logfiles: + logtime = os.path.getmtime(path) + if logtime < A1Time - 300: + del logfiles[ logfiles.index(path)] empire=0 for lfile in logfiles: with open(lfile, 'r') as lf: @@ -159,9 +167,9 @@ x1,x2,y1,y2 = axis() newY2=y2 for yi in range(1, 10): - if 1.05*ymax < yi*y2/10: - newY2= yi*y2/10 - break + if 1.05*ymax < yi*y2/10: + newY2= yi*y2/10 + break print "y1: %.1f ; ymin: %.1f ; newY2/100: %.1f"%(y1, ymin, newY2/100) y1 = max(y1, 4, ymin, newY2/100) #axis( (x1,min(x2,200),y1,y2)) |