From: <dil...@us...> - 2014-06-02 17:32:34
|
Revision: 7136 http://sourceforge.net/p/freeorion/code/7136 Author: dilvish-fo Date: 2014-06-02 17:32:31 +0000 (Mon, 02 Jun 2014) Log Message: ----------- AI adjustment to Sloths Supply patch, plus a tweak to Elevators so they are not pointlessly buildable on Asteroids Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp trunk/FreeOrion/default/AI/AIDependencies.py trunk/FreeOrion/default/AI/ColonisationAI.py trunk/FreeOrion/default/AI/MilitaryAI.py trunk/FreeOrion/default/AI/charting/lineEndingChecker.py trunk/FreeOrion/default/buildings.txt trunk/FreeOrion/default/species.txt trunk/FreeOrion/python/PythonEmpireWrapper.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/Empire/Empire.cpp 2014-06-02 17:32:31 UTC (rev 7136) @@ -1819,6 +1819,10 @@ void Empire::UpdateSupply(const std::map<int, std::set<int> >& starlanes) { //std::cout << "Empire::UpdateSupply for empire " << this->Name() << std::endl; + // Please also update PythonEmpireWrapper.cpp:CalculateSupplyUpdate if there is a change to the supply propagation rules: + // (i) there is a set of supply sources in systems, (ii) propagating supply drops one per starlane jump, (iii) propagation is blocked + // into and out of any systems not in SupplyUnobstructedSystems, and (iv) a system gets the highest supply thus available to it. + m_supply_starlane_traversals.clear(); m_supply_starlane_obstructed_traversals.clear(); m_fleet_supplyable_system_ids.clear(); Modified: trunk/FreeOrion/default/AI/AIDependencies.py =================================================================== --- trunk/FreeOrion/default/AI/AIDependencies.py 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/AI/AIDependencies.py 2014-06-02 17:32:31 UTC (rev 7136) @@ -1,3 +1,4 @@ +import freeOrionAIInterface as fo # pylint: disable=import-error metabolimBoostMap= { "ORGANIC": ["FRUIT_SPECIAL", "PROBIOTIC_SPECIAL", "SPICE_SPECIAL"], "LITHIC":["CRYSTALS_SPECIAL", "ELERIUM_SPECIAL", "MINERALS_SPECIAL"], @@ -16,8 +17,26 @@ shipUpkeep = 0.01 outposting_tech = "CON_ENV_ENCAPSUL" -supply_range_techs = ["CON_ORBITAL_CON", "CON_CONTGRAV_ARCH", "CON_GAL_INFRA"] +supply_range_techs = {"CON_ORBITAL_CON":1, "CON_CONTGRAV_ARCH":1, "CON_GAL_INFRA":1} +supply_by_size = { int(fo.planetSize.tiny): 2, + int(fo.planetSize.small): 1, + int(fo.planetSize.large): -1, + int(fo.planetSize.huge): -2, + int(fo.planetSize.gasGiant):-1, + } +# building supply bonuses are keyed by planet size; key -1 stands for any planet size +building_supply = { "BLD_IMPERIAL_PALACE": {-1: 2}, + "BLD_MEGALITH": {-1: 2}, + "BLD_SPACE_ELEVATOR": { int(fo.planetSize.tiny): 1, + int(fo.planetSize.small): 2, + int(fo.planetSize.medium): 3, + int(fo.planetSize.large): 4, + int(fo.planetSize.huge): 5, + int(fo.planetSize.gasGiant): 4, + }, + } + sing_tech_name = "PRO_SINGULAR_GEN" prod_auto_name = "PRO_SENTIENT_AUTOMATION" Modified: trunk/FreeOrion/default/AI/ColonisationAI.py =================================================================== --- trunk/FreeOrion/default/AI/ColonisationAI.py 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/AI/ColonisationAI.py 2014-06-02 17:32:31 UTC (rev 7136) @@ -31,6 +31,8 @@ annexableRing2=set() annexableRing3=set() annexablePlanetIDs=set() +systems_by_supply_tier = {} +system_supply = {} curBestMilShipRating = 20 allColonyOpportunities = {} gotRuins=False @@ -89,6 +91,8 @@ allColonyOpportunities.clear() unowned_planet_ids.clear() empireOutpostIDs.clear() + systems_by_supply_tier.clear() + system_supply.clear() def ratePilotingTag(tagList): grade = 2.0 @@ -109,9 +113,7 @@ return 0.0 return ratePilotingTag(thisSpec.tags) - def check_supply(): - # get suppliable systems and planets supp_timing = [ [], [] ] universe = fo.getUniverse() @@ -148,12 +150,16 @@ annexableRing2.clear() annexableRing3.clear() annexablePlanetIDs.clear() - supply_distance = 1 + systems_by_supply_tier.clear() + system_supply.clear() + supply_distance = 0 for tech in AIDependencies.supply_range_techs: if empire.getTechStatus(tech) == fo.techStatus.complete: - supply_distance += 1 - if foAI.foAIstate.aggression >= fo.aggression.aggressive: - supply_distance += 1 + supply_distance += AIDependencies.supply_range_techs[tech] + foAI.foAIstate.misc['supply_tech'] = supply_distance + supply_distance += 4 # 2 for up to great supply species, and 2 for possible tiny planets + #if foAI.foAIstate.aggression >= fo.aggression.aggressive: + # supply_distance += 1 for sysID in empire.fleetSupplyableSystemIDs: annexableSystemIDs.add(sysID) #add fleet supplyable system for nID in universe.getImmediateNeighbors(sysID, empireID): @@ -164,24 +170,50 @@ annexableRing1.add(nID) annexableRing1.difference_update(annexableSystemIDs) annexableSystemIDs.update(annexableRing1) - print "First Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing1) if supply_distance > 2: 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 supply_distance > 3: 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)) supp_timing[0].append( time() ) - supp_timing[1].append( "Determining Annexible Systems" ) + supp_timing[1].append( "Determining Annexable Systems" ) + print "First Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing1) + print "Second Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing2) + print "Third Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(annexableRing3) + print "standard supply calc took ", supp_timing[0][-1]-supp_timing[0][-2] + print + new_supply_map = empire.supplyProjections(-3, False) + new_time = time() + print "New Supply Calc:" + print "Known Systems:", list(universe.systemIDs) + print "Base Supply:", dictFromMap(empire.systemSupplyRanges) + for el in new_supply_map: + #print PlanetUtilsAI.sysNameIDs([el.key()]), ' -- ', el.data() + systems_by_supply_tier.setdefault(min(0, el.data()), []).append(el.key()) + system_supply[el.key()] = el.data() + print "New Supply connected systems: ", PlanetUtilsAI.sysNameIDs(systems_by_supply_tier.get(0, [])) + print "New First Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(systems_by_supply_tier.get(-1, [])) + print "New Second Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(systems_by_supply_tier.get(-2, [])) + print "New Third Ring of annexable systems: ", PlanetUtilsAI.sysNameIDs(systems_by_supply_tier.get(-3, [])) + print "new supply calc took ", new_time-supp_timing[0][-1] + annexableSystemIDs.clear() #TODO: distinguish colony-annexable systems and outpost-annexable systems + annexableRing1.clear() + annexableRing2.clear() + annexableRing3.clear() + annexableRing1.update(systems_by_supply_tier.get(-1, [])) + annexableRing2.update(systems_by_supply_tier.get(-2, [])) + annexableRing3.update(systems_by_supply_tier.get(-3, [])) + #annexableSystemIDs.update(systems_by_supply_tier.get(0, []), annexableRing1, annexableRing2, annexableRing3) + for jumps in range(0, -1-supply_distance, -1): + annexableSystemIDs.update(systems_by_supply_tier.get(jumps, [])) return supp_timing, fleetSupplyablePlanetIDs def survey_universe(): @@ -733,6 +765,7 @@ capitalID = PlanetUtilsAI.getCapital() homeworld = universe.getPlanet(capitalID) planet = universe.getPlanet(planetID) + planet_size = planet.size this_sysid = planet.systemID distanceFactor = 0 if homeworld: @@ -763,7 +796,15 @@ if AIstate.colonizedSystems.get(this_sysid, []) not in [ [], [planetID]]: #if existing presence is target planet, don't count haveExistingPresence=True system = universe.getSystem(this_sysid) - sys_status = foAI.foAIstate.systemStatus.get(planet.systemID, {}) + sys_status = foAI.foAIstate.systemStatus.get(this_sysid, {}) + + sys_supply = system_supply.get(this_sysid, -99) + planet_supply = AIDependencies.supply_by_size.get( int(planet_size), 0 ) + planet_build_names = [universe.getObject(bldg).buildingTypeName for bldg in planet.buildingIDs] + for bldType in set(planet_build_names).intersection(AIDependencies.building_supply): + planet_supply += sum([AIDependencies.building_supply.get(bldType, {}).get(int(psize),0) for psize in [-1, planet.size]]) + planet_supply += foAI.foAIstate.misc.get('supply_tech', 0) + myrating = sys_status.get('myFleetRating', 0) fleet_threat_ratio = (sys_status.get('fleetThreat', 0) - myrating ) / float(curBestMilShipRating) monster_threat_ratio = sys_status.get('monsterThreat', 0) / float(curBestMilShipRating) @@ -956,6 +997,13 @@ if haveExistingPresence: detail.append("preexisting system colony") retval *=1.5 + if sys_supply < 0: + if sys_supply + planet_supply >= 0: + retval += 50*(planet_supply - max(-3, sys_supply)) + else: + retval += 50*(planet_supply + sys_supply) # (a penalty) + elif planet_supply > sys_supply and (sys_supply < 2): #TODO: check min neighbor supply + retval += 25*(planet_supply - sys_supply) return int(retval) else: #colonization mission if not species: @@ -968,6 +1016,7 @@ popTagMod = 1.0 indTagMod = 1.0 resTagMod = 1.0 + supplyTagMod = 0.0 AITags="" for tag in [tag1 for tag1 in tagList if "AI_TAG" in tag1]: tagParts = tag.split('_') @@ -980,7 +1029,18 @@ indTagMod = grade elif tagType =="RESEARCH": resTagMod = grade + elif tagType =="SUPPLY": + supplyTagMod = {'BAD':0, 'AVERAGE':1, 'GOOD':1, 'GREAT':2, 'ULTIMATE':3 }.get(tagParts[2], 0) + planet_supply += supplyTagMod + if sys_supply <= 0: + if sys_supply + planet_supply >= 0: + retval += 100*(planet_supply - max(-3, sys_supply)) + else: + retval += 200*(planet_supply + sys_supply) # (a penalty) + elif (planet_supply > sys_supply) and (sys_supply == 1): #TODO: check min neighbor supply + retval += 50*(planet_supply - sys_supply) + #if AITags != "": # print "Species %s has AITags %s"%(specName, AITags) @@ -1187,13 +1247,6 @@ return 0 retval += max(indVal+asteroidBonus+gasGiantBonus, researchBonus, growthVal)+fixedInd + fixedRes - if this_sysid in annexableRing1: - retval += 10 - elif this_sysid in annexableRing2: - retval += 20 - elif this_sysid in annexableRing3: - retval += 10 - retval *= priorityScaling if thrtFactor < 1.0: Modified: trunk/FreeOrion/default/AI/MilitaryAI.py =================================================================== --- trunk/FreeOrion/default/AI/MilitaryAI.py 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/AI/MilitaryAI.py 2014-06-02 17:32:31 UTC (rev 7136) @@ -355,7 +355,8 @@ print "-----------------" otherTargetedSystemIDs = [] - targetableIDs = ColonisationAI.annexableSystemIDs.union( empire.fleetSupplyableSystemIDs ) + #targetableIDs = ColonisationAI.annexableSystemIDs.union( empire.fleetSupplyableSystemIDs ) + targetableIDs = set(ColonisationAI.systems_by_supply_tier.get(0, []) + ColonisationAI.systems_by_supply_tier.get(1, [])) for sysID in AIstate.opponentSystemIDs: if sysID in targetableIDs: otherTargetedSystemIDs.append(sysID) Modified: trunk/FreeOrion/default/AI/charting/lineEndingChecker.py =================================================================== --- trunk/FreeOrion/default/AI/charting/lineEndingChecker.py 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/AI/charting/lineEndingChecker.py 2014-06-02 17:32:31 UTC (rev 7136) @@ -2,7 +2,7 @@ import glob # adjust this to point to your main FreeOrion directory -FOHome = os.path.expanduser('~/programs/freeorion_test/') +FOHome = os.path.expanduser('~/programs/freeorion_dev1/') #if testAll is true the script will crawl through all FO files, skipping any folders in dirs_to_skip # checking files but not fixing @@ -12,10 +12,10 @@ # file_list is a whitespace-separated list of file pathnames (relative to FOHome) to check (and possibly fix) if testAll is false # the pathnames should NOT have leading slash: for example, # use "default/buildings.txt", NOT "/default/buildings.txt" -file_list = "default/stringtables/en.txt" +file_list = "Supply_Tweaked7-remake.patch" # if testAll is false, therefore using file_list, fixfiles controls whether CRLF's will be converted to LF's -fixfiles = False +fixfiles = True def checkLineEndings(filename, fix=False): thisFile = open(filename, 'r') @@ -70,9 +70,9 @@ if not testAll: print for fname in file_list.split(): - results1=checkLineEndings(fname, fix=False) + results1=checkLineEndings(fname, fix=fixfiles) if fixfiles and results1.keys()!=['LF']: - results2=checkLineEndings(fname, fix=True) + results2=checkLineEndings(fname, fix=False) print fname, "line endings were", results1, "now are", results2 else: print fname, "line endings are", results1 Modified: trunk/FreeOrion/default/buildings.txt =================================================================== --- trunk/FreeOrion/default/buildings.txt 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/buildings.txt 2014-06-02 17:32:31 UTC (rev 7136) @@ -703,6 +703,7 @@ location = And [ Planet Not Contains Building "BLD_SPACE_ELEVATOR" + Not Planet type = Asteroids OwnedBy TheEmpire Source.Owner TargetPopulation low = 1 ] Modified: trunk/FreeOrion/default/species.txt =================================================================== --- trunk/FreeOrion/default/species.txt 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/default/species.txt 2014-06-02 17:32:31 UTC (rev 7136) @@ -20,7 +20,7 @@ CanProduceShips CanColonize - tags = [ "LITHIC" "AI_TAG_BAD_RESEARCH" ] + tags = [ "LITHIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -56,7 +56,7 @@ Native CanProduceShips - tags = [ "SELF_SUSTAINING" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_GOOD_RESEARCH" "AI_TAG_GOOD_SHIELDS" ] + tags = [ "SELF_SUSTAINING" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_GOOD_RESEARCH" "AI_TAG_GOOD_SHIELDS" "AI_TAG_GREAT_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -131,7 +131,7 @@ gameplay_description = "SP_BEIGEGOO_GAMEPLAY_DESC" Native - Tags = [ "ROBOTIC" "AI_TAG_GOOD_POPULATION" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_NO_RESEARCH" ] + Tags = [ "ROBOTIC" "AI_TAG_GOOD_POPULATION" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_NO_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -170,7 +170,7 @@ CanProduceShips CanColonize - tags = [ "PHOTOTROPHIC" "AI_TAG_GREAT_RESEARCH" ] + tags = [ "PHOTOTROPHIC" "AI_TAG_GREAT_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -208,7 +208,7 @@ CanProduceShips CanColonize - tags = [ "ROBOTIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_RESEARCH" ] + tags = [ "ROBOTIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -245,7 +245,7 @@ Native CanProduceShips - tags = [ "PHOTOTROPHIC" "AI_TAG_NO_INDUSTRY" ] + tags = [ "PHOTOTROPHIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ /* [[HAS_INDUSTRY_FOCUS]]*/ @@ -282,7 +282,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_BAD_WEAPONS"] + tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_BAD_WEAPONS" "AI_TAG_AVERAGE_SUPPLY"] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -320,7 +320,7 @@ CanProduceShips CanColonize - tags = ["ORGANIC" "XENOPHOBIC" "AI_TAG_GREAT_WEAPONS"] + tags = ["ORGANIC" "XENOPHOBIC" "AI_TAG_GREAT_WEAPONS" "AI_TAG_AVERAGE_SUPPLY"] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -367,7 +367,7 @@ CanProduceShips CanColonize - tags = [ "LITHIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_ULTIMATE_INDUSTRY" "AI_TAG_BAD_POPULATION" ] + tags = [ "LITHIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_ULTIMATE_INDUSTRY" "AI_TAG_BAD_POPULATION" "AI_TAG_GREAT_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -406,7 +406,7 @@ CanProduceShips CanColonize - tags = [ "ROBOTIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_WEAPONS"] + tags = [ "ROBOTIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_WEAPONS" "AI_TAG_GREAT_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -450,7 +450,7 @@ CanProduceShips CanColonize - Tags = [ "ROBOTIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_WEAPONS" ] + Tags = [ "ROBOTIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_WEAPONS" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -497,7 +497,7 @@ description = "SP_EXPERIMENTOR_DESC" gameplay_description = "SP_EXPERIMENTOR_GAMEPLAY_DESC" - tags = [ "SELF_SUSTAINING" "AI_TAG_NO_INDUSTRY" "AI_TAG_ULTIMATE_RESEARCH" "AI_TAG_GOOD_POPULATION" ] + tags = [ "SELF_SUSTAINING" "AI_TAG_NO_INDUSTRY" "AI_TAG_ULTIMATE_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ /*[[HAS_INDUSTRY_FOCUS]]*/ @@ -535,7 +535,7 @@ gameplay_description = "SP_FIFTYSEVEN_GAMEPLAY_DESC" Native - tags = [ "ORGANIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_ULTIMATE_RESEARCH" "AI_TAG_BAD_POPULATION" ] + tags = [ "ORGANIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_ULTIMATE_RESEARCH" "AI_TAG_BAD_POPULATION" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ /*[[HAS_INDUSTRY_FOCUS]]*/ @@ -572,7 +572,7 @@ //CanColonize - tags = [ "ORGANIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_POPULATION" ] + tags = [ "ORGANIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_POPULATION" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -612,7 +612,7 @@ CanProduceShips CanColonize - tags = [ "LITHIC" "TELEPATHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_RESEARCH" ] + tags = [ "LITHIC" "TELEPATHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_RESEARCH" "AI_TAG_GREAT_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -648,7 +648,7 @@ Native CanProduceShips - tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_RESEARCH" ] + tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -685,7 +685,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_BAD_WEAPONS"] + tags = [ "ORGANIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_BAD_WEAPONS" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -725,7 +725,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "AI_TAG_GOOD_WEAPONS" ] + tags = [ "ORGANIC" "AI_TAG_GOOD_WEAPONS" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -765,7 +765,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "STYLISH" ] + tags = [ "ORGANIC" "STYLISH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -805,7 +805,7 @@ CanProduceShips CanColonize - tags = [ "SELF_SUSTAINING" "AI_TAG_GREAT_INDUSTRY" ] + tags = [ "SELF_SUSTAINING" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -842,7 +842,7 @@ CanProduceShips CanColonize - tags = [ "PHOTOTROPHIC" "TELEPATHIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_GOOD_POPULATION" ] + tags = [ "PHOTOTROPHIC" "TELEPATHIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -883,7 +883,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_GREAT_WEAPONS"] + tags = [ "ORGANIC" "AI_TAG_BAD_RESEARCH" "AI_TAG_GREAT_WEAPONS" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -921,7 +921,7 @@ gameplay_description = "SP_NYMNMN_GAMEPLAY_DESC" Native - tags = [ "SELF_SUSTAINING" "AI_TAG_NO_INDUSTRY" "AI_TAG_BAD_POPULATION" ] + tags = [ "SELF_SUSTAINING" "AI_TAG_NO_INDUSTRY" "AI_TAG_BAD_POPULATION" "AI_TAG_BAD_SUPPLY" ] foci = [ /*[[HAS_INDUSTRY_FOCUS]]*/ @@ -959,7 +959,7 @@ gameplay_description = "SP_OURBOOLS_GAMEPLAY_DESC" Native - tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" ] + tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -998,7 +998,7 @@ //CanColonize - tags = [ "ORGANIC" "AI_TAG_NO_RESEARCH" ] + tags = [ "ORGANIC" "AI_TAG_NO_RESEARCH" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1033,7 +1033,7 @@ gameplay_description = "SP_RAAAGH_GAMEPLAY_DESC" Native - tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_NO_RESEARCH" ] + tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_NO_RESEARCH" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1071,7 +1071,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" ] + tags = [ "ORGANIC" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1111,7 +1111,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_POPULATION" ] + tags = [ "ORGANIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_GOOD_POPULATION" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1150,7 +1150,7 @@ //CanColonize - Tags = [ "ROBOTIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_WEAPONS"] + Tags = [ "ROBOTIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_BAD_RESEARCH" "AI_TAG_BAD_WEAPONS" "AI_TAG_GREAT_SUPPLY" ] foci = [ /*[[HAS_INDUSTRY_FOCUS]]*/ @@ -1188,7 +1188,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_BAD_INDUSTRY" ] + tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_BAD_INDUSTRY" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1225,7 +1225,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "ROBOTIC" "LITHIC" "PHOTOTROPHIC" "SELF_SUSTAINING" "TELEPATHIC" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" ] + tags = [ "ORGANIC" "ROBOTIC" "LITHIC" "PHOTOTROPHIC" "SELF_SUSTAINING" "TELEPATHIC" "AI_TAG_GREAT_INDUSTRY" "AI_TAG_GREAT_RESEARCH" "AI_TAG_GOOD_POPULATION" "AI_TAG_ULTIMATE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1276,7 +1276,7 @@ CanProduceShips CanColonize - tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_WEAPONS"] + tags = [ "ORGANIC" "TELEPATHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_WEAPONS" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1312,7 +1312,7 @@ gameplay_description = "SP_TRENCHERS_GAMEPLAY_DESC" Native - Tags = [ "ROBOTIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_NO_RESEARCH" ] + Tags = [ "ROBOTIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_NO_RESEARCH" "AI_TAG_BAD_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1349,7 +1349,7 @@ CanProduceShips CanColonize - tags = [ "SELF_SUSTAINING" "TELEPATHIC" "XENOPHOBIC" ] + tags = [ "SELF_SUSTAINING" "TELEPATHIC" "XENOPHOBIC" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1397,7 +1397,7 @@ CanProduceShips CanColonize - tags = [ "LITHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_RESEARCH" ] + tags = [ "LITHIC" "AI_TAG_GOOD_INDUSTRY" "AI_TAG_BAD_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1432,7 +1432,7 @@ gameplay_description = "SP_VOLP_GAMEPLAY_DESC" Native - tags = [ "LITHIC" "AI_TAG_GOOD_POPULATION" ] + tags = [ "LITHIC" "AI_TAG_GOOD_POPULATION" "AI_TAG_ULTIMATE_SUPPLY" ] foci = [ [[HAS_INDUSTRY_FOCUS]] @@ -1469,7 +1469,7 @@ gameplay_description = "SP_HIDDENGARDENER_GAMEPLAY_DESC" Native - tags = [ "ORGANIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_NO_RESEARCH" ] + tags = [ "ORGANIC" "AI_TAG_NO_INDUSTRY" "AI_TAG_NO_RESEARCH" "AI_TAG_AVERAGE_SUPPLY" ] foci = [ [[HAS_GROWTH_FOCUS]] Modified: trunk/FreeOrion/python/PythonEmpireWrapper.cpp =================================================================== --- trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2014-06-02 17:12:20 UTC (rev 7135) +++ trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2014-06-02 17:32:31 UTC (rev 7136) @@ -94,7 +94,113 @@ return retval; } boost::function<std::vector<IntPair>(const Empire&)> obstructedStarlanesFunc = &obstructedStarlanesP; + +void CalculateSupplyUpdate(const std::map<int, std::set<int> >& starlanes, + const std::map<int, int>& supply_system_ranges, + const std::set<int>& supply_unobstructed_systems, + std::map<int, int>& propegating_supply_ranges, + int min_tracked_supply = 0, + bool obstructed = true ) // Note: must be called with min_tracked_supply = 0 to give the standard result +{ + // store supply range in jumps of all unobstructed systems before + // propegation, and add to list of systems to propegate from. + std::list<int> propegating_systems_list; + for (std::map<int, int>::const_iterator it = supply_system_ranges.begin(); + it != supply_system_ranges.end(); ++it) + { + if (!obstructed || (supply_unobstructed_systems.find(it->first) != supply_unobstructed_systems.end())) + propegating_supply_ranges.insert(*it); + else + propegating_supply_ranges[it->first] = min_tracked_supply; + + // add system to list of systems to popegate supply from + propegating_systems_list.push_back(it->first); + } + + // iterate through list of accessible systems, processing each in order it + // was added (like breadth first search) until no systems are left able to + // further propregate + std::list<int>::iterator sys_list_it = propegating_systems_list.begin(); + std::list<int>::iterator sys_list_end = propegating_systems_list.end(); + while (sys_list_it != sys_list_end) { + int cur_sys_id = *sys_list_it; + int cur_sys_range = propegating_supply_ranges[cur_sys_id]; // range away from this system that supplies can be transported + + if (cur_sys_range <= min_tracked_supply) { + // can't propegate supply out a system that has no range if min_tracked_supply is zero; + // if min_tracked_supply is negative, then may be able to continue propagating. A negative supply + // number indicates number of jumps to nearest supply + ++sys_list_it; + continue; + } + + // can propegate further, if adjacent systems have smaller supply range + // than one less than this system's range + std::map<int, std::set<int> >::const_iterator system_it = starlanes.find(cur_sys_id); + if (system_it == starlanes.end()) { + // no starlanes out of this system + ++sys_list_it; + continue; + } + + const std::set<int>& starlane_ends = system_it->second; + for (std::set<int>::const_iterator lane_it = starlane_ends.begin(); + lane_it != starlane_ends.end(); ++lane_it) + { + int lane_end_sys_id = *lane_it; + + if (obstructed && (supply_unobstructed_systems.find(lane_end_sys_id) == supply_unobstructed_systems.end())) { + // can't propegate here + continue; + } + + // compare next system's supply range to this system's supply range. propegate if necessary. + std::map<int, int>::const_iterator lane_end_sys_it = propegating_supply_ranges.find(lane_end_sys_id); + if (lane_end_sys_it == propegating_supply_ranges.end() || lane_end_sys_it->second <= cur_sys_range) { + // next system has no supply yet, or its range equal to or smaller than this system's + + // update next system's range, if propegating from this system would make it larger + if (lane_end_sys_it == propegating_supply_ranges.end() || lane_end_sys_it->second < cur_sys_range - 1) { + // update with new range + propegating_supply_ranges[lane_end_sys_id] = cur_sys_range - 1; + // add next system to list of systems to propegate further + propegating_systems_list.push_back(lane_end_sys_id); + } + } + } + ++sys_list_it; + sys_list_end = propegating_systems_list.end(); + } +} + + + std::map<int,int> supplyProjectionsP(const Empire& empire, int min_tracked_supply, bool obstructed) { + std::map< int, std::set< int > > starlanes = empire.KnownStarlanes(); + const std::map<int, int>& supply_system_ranges = empire.SystemSupplyRanges(); + std::map<int, int> propegating_supply_ranges; + + if (obstructed) { + const std::set<int>& supply_unobstructed_systems = empire.SupplyUnobstructedSystems(); + CalculateSupplyUpdate( starlanes, + supply_system_ranges, + supply_unobstructed_systems, + propegating_supply_ranges, + min_tracked_supply, + true ); // Note: must be called with min_tracked_supply = 0 to give the standard result + } else { + std::set<int> known_systems; + CalculateSupplyUpdate( starlanes, + supply_system_ranges, + known_systems, + propegating_supply_ranges, + min_tracked_supply, + false); // Note: must be called with min_tracked_supply = 0 to give the standard result + } + return propegating_supply_ranges; + } + boost::function<std::map<int,int>(const Empire&, int min_tracked_supply, bool obstructed)> supplyProjectionsFunc = &supplyProjectionsP; + typedef std::pair<float, int> FloatIntPair; typedef PairToTupleConverter<float, int> FloatIntPairConverter; @@ -288,6 +394,7 @@ .add_property("fleetSupplyableSystemIDs", make_function(&Empire::FleetSupplyableSystemIDs, return_internal_reference<>())) .add_property("supplyUnobstructedSystems", make_function(&Empire::SupplyUnobstructedSystems, return_internal_reference<>())) + .add_property("systemSupplyRanges", make_function(&Empire::SystemSupplyRanges, return_internal_reference<>())) .add_property("numSitReps", &Empire::NumSitRepEntries) .def("getSitRep", make_function( @@ -299,7 +406,11 @@ .def("obstructedStarlanes", make_function(obstructedStarlanesFunc, return_value_policy<return_by_value>(), boost::mpl::vector<std::vector<IntPair>, const Empire&>() - )) + )) + .def("supplyProjections", make_function(supplyProjectionsFunc, + return_value_policy<return_by_value>(), + boost::mpl::vector<std::map<int, int>, const Empire&, int, bool>() + )) ; //////////////////// |