def startNewGame(aggression=fo.aggression.aggressive): # pylint: disable=invalid-name """Called by client when a new game is started (but not when a game is loaded). Should clear any pre-existing state and set up whatever is needed for AI to generate orders.""" empire = fo.getEmpire() if empire.eliminated: print "This empire has been eliminated. Ignoring new game start message." return turn_timer.start("Server Processing") print "New game started, AI Aggression level %d (%s)" % (aggression, UserString(_aggression_names[aggression])) # initialize AIstate global foAIstate print "Initializing foAIstate..." foAIstate = AIstate.AIstate(aggression) foAIstate.session_start_cleanup() print "Initialization of foAIstate complete!" print "Trying to rename our homeworld..." planet_id = PlanetUtilsAI.get_capital() universe = fo.getUniverse() if planet_id is not None and planet_id != -1: planet = universe.getPlanet(planet_id) new_name = " ".join([random.choice(_capitals.get(aggression, []) or [" "]).strip(), planet.name]) print " Renaming to %s..." % new_name res = fo.issueRenameOrder(planet_id, new_name) print " Result: %d; Planet is now named %s" % (res, planet.name) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" if fo.getEmpire() is None: print "This client has no empire. Doing nothing to resume loaded game." return if fo.getEmpire().eliminated: print "This empire has been eliminated. Ignoring resume loaded game." return turn_timer.start("Server Processing") global foAIstate print "Resuming loaded game" if not saved_state_string: print_error("AI given empty state-string to resume from; this is expected if the AI is assigned to an empire " "previously run by a human, but is otherwise an error. AI will be set to Aggressive.") foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() else: try: # loading saved state # pre load code foAIstate = pickle.loads(saved_state_string) except Exception as e: # assigning new state foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() print_error("Fail to load aiState from saved game: %s" % e) aggression_trait = foAIstate.character.get_trait(Aggression) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" if fo.getEmpire() is None: print "This client has no empire. Doing nothing to resume loaded game." return if fo.getEmpire().eliminated: print "This empire has been eliminated. Ignoring resume loaded game." return turn_timer.start("Server Processing") global foAIstate print "Resuming loaded game" if not saved_state_string: error("AI given empty state-string to resume from; this is expected if the AI is assigned to an empire " "previously run by a human, but is otherwise an error. AI will be set to Aggressive.") foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() else: try: # loading saved state # pre load code foAIstate = pickle.loads(saved_state_string) except Exception as e: # assigning new state foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() error("Fail to load aiState from saved game: %s" % e, exc_info=True) aggression_trait = foAIstate.character.get_trait(Aggression) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" if fo.getEmpire().eliminated: print "This empire has been eliminated. Ignoring resume loaded game." return turn_timer.start("Server Processing") global foAIstate print "Resuming loaded game" try: # loading saved state # pre load code foAIstate = pickle.loads(saved_state_string) except Exception as e: # assigning new state foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() print_error("Fail to load aiState form saved game: %s" % e) aggression_trait = foAIstate.character.get_trait(Aggression) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def startNewGame(aggression_input=fo.aggression.aggressive): # pylint: disable=invalid-name """Called by client when a new game is started (but not when a game is loaded). Should clear any pre-existing state and set up whatever is needed for AI to generate orders.""" empire = fo.getEmpire() if empire.eliminated: print "This empire has been eliminated. Ignoring new game start message." return turn_timer.start("Server Processing") # initialize AIstate global foAIstate print "Initializing foAIstate..." foAIstate = AIstate.AIstate(aggression_input) aggression_trait = foAIstate.character.get_trait(Aggression) print "New game started, AI Aggression level %d (%s)" % ( aggression_trait.key, get_trait_name_aggression(foAIstate.character)) foAIstate.session_start_cleanup() print "Initialization of foAIstate complete!" print "Trying to rename our homeworld..." planet_id = PlanetUtilsAI.get_capital() universe = fo.getUniverse() if planet_id is not None and planet_id != INVALID_ID: planet = universe.getPlanet(planet_id) new_name = " ".join([random.choice(possible_capitals(foAIstate.character)).strip(), planet.name]) print " Renaming to %s..." % new_name res = fo.issueRenameOrder(planet_id, new_name) print " Result: %d; Planet is now named %s" % (res, planet.name) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def _pre_game_start(empire_id, aistate): """ Configuration that should be done before AI start operating. """ aggression_trait = aistate.character.get_trait(Aggression) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity() configure_debug_chat(empire_id)
def exclude_tech(tech_name): return ( (foAI.foAIstate.aggression < AIDependencies.TECH_EXCLUSION_MAP_1.get( tech_name, fo.aggression.invalid)) or (foAI.foAIstate.aggression > AIDependencies.TECH_EXCLUSION_MAP_2.get( tech_name, fo.aggression.maniacal)) or tech_name in TechsListsAI.unusable_techs())
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" if fo.getEmpire() is None: print "This client has no empire. Doing nothing to resume loaded game." return if fo.getEmpire().eliminated: print "This empire has been eliminated. Ignoring resume loaded game." return turn_timer.start("Server Processing") global foAIstate print "Resuming loaded game" if not saved_state_string: error( "AI given empty state-string to resume from; this is expected if the AI is assigned to an empire " "previously run by a human, but is otherwise an error. AI will be set to Aggressive." ) foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() else: import savegame_codec try: # loading saved state foAIstate = savegame_codec.load_savegame_string(saved_state_string) except Exception as e: # assigning new state foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() error( "Failed to load the AIstate from the savegame. The AI will" " play with a fresh AIstate instance with aggression level set" " to 'aggressive'. The behaviour of the AI may be different" " than in the original session. The error raised was: %s" % e, exc_info=True) aggression_trait = foAIstate.character.get_trait(Aggression) diplomatic_corp_configs = { fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp } global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get( aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity() debug('Size of already issued orders: ' + str(fo.getOrders().size))
def startNewGame(aggression_input=fo.aggression.aggressive): # pylint: disable=invalid-name """Called by client when a new game is started (but not when a game is loaded). Should clear any pre-existing state and set up whatever is needed for AI to generate orders.""" empire = fo.getEmpire() if empire is None: print "This client has no empire. Ignoring new game start message." return if empire.eliminated: info( "This empire has been eliminated. Ignoring new game start message." ) return turn_timer.start("Server Processing") # initialize AIstate global foAIstate debug("Initializing foAIstate...") foAIstate = AIstate.AIstate(aggression_input) aggression_trait = foAIstate.character.get_trait(Aggression) debug( "New game started, AI Aggression level %d (%s)" % (aggression_trait.key, get_trait_name_aggression(foAIstate.character))) foAIstate.session_start_cleanup() debug("Initialization of foAIstate complete!") debug("Trying to rename our homeworld...") planet_id = PlanetUtilsAI.get_capital() universe = fo.getUniverse() if planet_id is not None and planet_id != INVALID_ID: planet = universe.getPlanet(planet_id) new_name = " ".join([ random.choice(possible_capitals(foAIstate.character)).strip(), planet.name ]) debug(" Renaming to %s..." % new_name) res = fo.issueRenameOrder(planet_id, new_name) debug(" Result: %d; Planet is now named %s" % (res, planet.name)) diplomatic_corp_configs = { fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp } global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get( aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def get_possible_projects(): """get possible projects""" preliminary_projects = [] empire = fo.getEmpire() for tech_name in fo.techs(): if empire.getTechStatus(tech_name) == fo.techStatus.researchable: preliminary_projects.append(tech_name) return set(preliminary_projects) - set(TechsListsAI.unusable_techs())
def get_possible_projects(): """get possible projects""" preliminary_projects = [] empire = fo.getEmpire() for tech_name in fo.techs(): if empire.getTechStatus(tech_name) == fo.techStatus.researchable: preliminary_projects.append(tech_name) return set(preliminary_projects)-set(TechsListsAI.unusable_techs())
def get_possible_projects(): """get possible projects""" preliminaryProjects = [] technames = fo.techs() # returns names of all techs empire = fo.getEmpire() for techname in technames: if empire.getTechStatus(techname) == fo.techStatus.researchable: preliminaryProjects.append(techname) unusableTechs = TechsListsAI.unusable_techs() return set(preliminaryProjects)-set(unusableTechs)
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" turn_timer.start("Server Processing") global foAIstate print "Resuming loaded game" try: # loading saved state # pre load code foAIstate = pickle.loads(saved_state_string) except Exception as e: # assigning new state foAIstate = AIstate.AIstate(fo.aggression.aggressive) foAIstate.session_start_cleanup() print_error("Fail to load aiState form saved game: %s" % e) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(foAIstate.aggression, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity()
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" if fo.getEmpire() is None: fatal("This client has no empire. Doing nothing to resume loaded game.") return if fo.getEmpire().eliminated: info("This empire has been eliminated. Ignoring resume loaded game.") return turn_timer.start("Server Processing") debug("Resuming loaded game") if not saved_state_string: error("AI given empty state-string to resume from; this is expected if the AI is assigned to an empire " "previously run by a human, but is otherwise an error. AI will be set to Aggressive.") aistate = create_new_aistate(fo.aggression.aggressive) aistate.session_start_cleanup() else: try: # loading saved state aistate = load_aistate(saved_state_string) except Exception as e: # assigning new state aistate = create_new_aistate(fo.aggression.aggressive) aistate.session_start_cleanup() error("Failed to load the AIstate from the savegame. The AI will" " play with a fresh AIstate instance with aggression level set" " to 'aggressive'. The behaviour of the AI may be different" " than in the original session. The error raised was: %s" % e, exc_info=True) aggression_trait = aistate.character.get_trait(Aggression) diplomatic_corp_configs = {fo.aggression.beginner: DiplomaticCorp.BeginnerDiplomaticCorp, fo.aggression.maniacal: DiplomaticCorp.ManiacalDiplomaticCorp} global diplomatic_corp diplomatic_corp = diplomatic_corp_configs.get(aggression_trait.key, DiplomaticCorp.DiplomaticCorp)() TechsListsAI.test_tech_integrity() debug('Size of already issued orders: ' + str(fo.getOrders().size))
def generate_classic_research_orders(): """generate research orders""" empire = fo.getEmpire() empire_id = empire.empireID aistate = get_aistate() enemies_sighted = aistate.misc.get("enemies_sighted", {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() resource_production = empire.resourceProduction(fo.resourceType.research) completed_techs = sorted(list(get_completed_techs())) _print_reserch_order_header(resource_production, completed_techs) # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() total_rp = empire.resourceProduction(fo.resourceType.research) tech_turns_left = {} if research_queue_list: debug("Techs currently at head of Research Queue:") for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft this_tech = fo.getTech(element.tech) if not this_tech: warning("Can't retrieve tech ", element.tech) continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs ] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: debug( " %25s allocated %6.2f RP (%d turns left)-- unlockable items: %s ", element.tech, element.allocation, tech_turns_left[element.tech], unlocked_items, ) else: debug( " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s ", element.tech, element.allocation, missing_prereqs, unlocked_items, ) debug("") # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() <= 2) or ((total_rp - research_queue.totalSpent) > 0): research_index = get_research_index() if fo.currentTurn() == 1: # do only this one on first turn, to facilitate use of a turn-1 savegame for testing of alternate # research strategies new_tech = ["LRN_PHYS_BRAIN", "GRO_PLANET_ECOL"] else: new_tech = (TechsListsAI.sparse_galaxy_techs(research_index) if galaxy_is_sparse else TechsListsAI.primary_meta_techs(research_index)) debug("Empire %s (%d) is selecting research index %d", empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs + research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: error("Desired tech '%s' appears to not exist" % tech) continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base ] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs + [tech]) cum_cost = 0 debug(" Enqueued Tech: %20s \t\t %8s \t %s", "Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost debug(" Enqueued Tech: %20s \t\t %8.0f \t %8.0f", name, this_cost, cum_cost) else: warning(" Failed attempt to enqueued Tech: " + name) except: # noqa: E722 warning(" Failed attempt to enqueued Tech: " + name, exc_info=True) debug("\n\nAll techs:") debug("=" * 20) alltechs = fo.techs() print_in_columns(sorted(fo.techs()), columns=3) debug("\n\nAll unqueued techs:") debug("=" * 20) # coveredTechs = new_tech+completed_techs print_in_columns([tn for tn in alltechs if tn not in tech_base], columns=3) debug("") if fo.currentTurn() == 1: return if True: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if (aistate.character.may_research_tech_classic(def_tech) and def_tech not in research_queue_list[:5] and not tech_is_complete(def_tech)): res = fo.issueEnqueueTechOrder( def_tech, min(3, len(research_queue_list))) debug( "Empire is very defensive, so attempted to fast-track %s, got result %d", def_tech, res) if False: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list and aistate.character.may_research_tech_classic( "CON_CONC_CAMP"): insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list) - 10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list and aistate.character.may_research_tech_classic( "SHP_DEFLECTOR_SHIELD"): insert_idx = min( insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if (cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete(cc_tech) and aistate.character.may_research_tech_classic(cc_tech)): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) debug( "Empire is very aggressive, so attempted to fast-track %s, got result %d", cc_tech, res) elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup nest_tech = Dep.NEST_DOMESTICATION_TECH artif_minds = Dep.LRN_ARTIF_MINDS_1 if have_nest() and not tech_is_complete(nest_tech): if artif_minds in research_queue_list: insert_idx = 1 + research_queue_list.index(artif_minds) else: insert_idx = 1 res = fo.issueEnqueueTechOrder(nest_tech, insert_idx) num_techs_accelerated += 1 debug( "Have a monster nest, so attempted to fast-track %s, got result %d", nest_tech, res) research_queue_list = get_research_queue_techs() # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(aistate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = next( iter(aistate.colonisablePlanetIDs.items()))[1] if len(aistate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = next( iter(aistate.colonisableOutpostIDs.items()))[1] need_improved_scouting = best_colony_site_score < 150 or best_outpost_site_score < 200 if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d", "CON_ORBITAL_CON", res, ) elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("CON_METRO_INFRA")): for supply_tech in [ _s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech) ]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d", supply_tech, res, ) else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete( "SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2 + num_techs_accelerated] and tech_is_complete( "PRO_FUSION_GEN" ): if "CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) debug( "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" "CON_ORBITAL_CON", res, ) research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (have_ruins() and not tech_is_complete("LRN_XENOARCH") and aistate.character.may_research_tech_classic("LRN_XENOARCH")): if artif_minds in research_queue_list: insert_idx = 7 + research_queue_list.index(artif_minds) elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if not tech_is_complete( xenoTech ) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 debug( "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d", xenoTech, res, ) research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [ ("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_ADAPTIVE_AUTOMATION", "PRO_ADAPTIVE_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_ADAPTIVE_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_ADAPTIVE_AUTOMATION"]), ( "PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", [ "PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I" ], ), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [ 0, 1, 2, ]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: debug( "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s", move_tech, target_slot, target_index, num_techs_accelerated, ) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: fo.issueEnqueueTechOrder(move_tech, target_index) debug( "Research: To prioritize %s, have advanced %s to slot %d", tech, move_tech, target_index) target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if have_asteroids(): insert_idx = (num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index("GRO_SYMBIOTIC_BIO")) ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 debug( "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d", ast_tech, res, ) research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = ( (1 + insert_idx) if "LRN_FORCE_FIELD" not in research_queue_list else max( 1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1)) for ast_tech in [ "SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS" ]: if not tech_is_complete( ast_tech ) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 debug( "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d", ast_tech, res, ) research_queue_list = get_research_queue_techs() if have_gas_giant() and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = (0 if "PRO_FUSION_GEN" not in research_queue_list else (1 + research_queue_list.index("PRO_FUSION_GEN"))) forcefields_idx = (0 if "LRN_FORCE_FIELD" not in research_queue_list else (1 + research_queue_list.index("LRN_FORCE_FIELD"))) insert_idx = max( fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 debug( "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d", "PRO_ORBITAL_GEN", res, ) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and (not got_xeno_gen): most_adequate = 0 for specName in get_colony_builders(): environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [ fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids, ]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max( most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if (xg_tech not in research_queue_list[:1 + num_techs_accelerated] and not tech_is_complete(xg_tech) and aistate.character.may_research_tech_classic( xg_tech)): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 debug( "Empire has poor colonizers, so attempted to fast-track %s, got result %d", xg_tech, res, ) research_queue_list = get_research_queue_techs() # # check to accelerate translinguistics if True: # just to help with cold-folding / organization # planet is needed to determine the cost. Without a capital we have bigger problems anyway... if not tech_is_complete("LRN_TRANSLING_THT") and translators_wanted(): insert_idx = num_techs_accelerated for dt_ech in [ "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if (dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech) and aistate.character.may_research_tech_classic(dt_ech)): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire wants to build translators, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" debug(fmt_str, dt_ech, res, resource_production, empire.population(), fo.currentTurn()) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in get_empire_planets_by_species(): this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break pop_threshold = 100 if got_telepathy else 300 if empire.population() > pop_threshold: insert_idx = num_techs_accelerated for dt_ech in [ "LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT" ]: if (dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech) and aistate.character.may_research_tech_classic( dt_ech)): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" debug(fmt_str, dt_ech, res, resource_production, empire.population(), fo.currentTurn()) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if aistate.character.may_research_tech_classic("LRN_QUANT_NET") and ( population_with_research_focus() >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 debug( "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d", qnTech, res, fo.currentTurn(), ) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and aistate.character.may_research_tech_classic("PRO_SINGULAR_GEN") and not tech_is_complete(Dep.PRO_SINGULAR_GEN) and tech_is_complete("LRN_EVERYTHING")): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(Dep.PRO_SINGULAR_GEN) sing_tech_list = [ pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req) ] sing_tech_list += [Dep.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated + 1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 debug( "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d", singTech, res, ) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list ] if len(missing_prereqs ) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx - 18)) # TODO: Remove the following example code # Example/Test code for the new ShipDesigner functionality techs = [ "SHP_WEAPON_4_2", "SHP_TRANSSPACE_DRIVE", "SHP_INTSTEL_LOG", "SHP_ASTEROID_HULLS", "" ] for tech in techs: this_tech = fo.getTech(tech) if not this_tech: debug("Invalid Tech specified") continue unlocked_items = this_tech.unlockedItems unlocked_hulls = [] unlocked_parts = [] for item in unlocked_items: if item.type == fo.unlockableItemType.shipPart: debug("Tech %s unlocks a ShipPart: %s", tech, item.name) unlocked_parts.append(item.name) elif item.type == fo.unlockableItemType.shipHull: debug("Tech %s unlocks a ShipHull: %s", tech, item.name) unlocked_hulls.append(item.name) if not (unlocked_parts or unlocked_hulls): debug("No new ship parts/hulls unlocked by tech %s", tech) continue old_designs = ShipDesignAI.WarShipDesigner().optimize_design( consider_fleet_count=False) new_designs = ShipDesignAI.WarShipDesigner().optimize_design( additional_hulls=unlocked_hulls, additional_parts=unlocked_parts, consider_fleet_count=False) if not (old_designs and new_designs): # AI is likely defeated; don't bother with logging error message continue old_rating, old_pid, old_design_id, old_cost, old_stats = old_designs[ 0] old_design = fo.getShipDesign(old_design_id) new_rating, new_pid, new_design_id, new_cost, new_stats = new_designs[ 0] new_design = fo.getShipDesign(new_design_id) if new_rating > old_rating: debug("Tech %s gives access to a better design!", tech) debug("old best design: Rating %.5f", old_rating) debug("old design specs: %s - %s", old_design.hull, list(old_design.parts)) debug("new best design: Rating %.5f", new_rating) debug("new design specs: %s - %s", new_design.hull, list(new_design.parts)) else: debug( "Tech %s gives access to new parts or hulls but there seems to be no military advantage.", tech)
def generate_research_orders(): """generate research orders""" report_adjustments = False empire = fo.getEmpire() empire_id = empire.empireID enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() print "Research Queue Management:" resource_production = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n" % resource_production print "Techs researched and available for use:" completed_techs = sorted(list(get_completed_techs())) tlist = completed_techs+3*[" "] tlines = zip(tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s" % tline print # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() inProgressTechs.clear() tech_turns_left = {} if research_queue_list: print "Techs currently at head of Research Queue:" for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft if element.allocation > 0.0: inProgressTechs[element.tech] = True this_tech = fo.getTech(element.tech) if not this_tech: print "Error: can't retrieve tech ", element.tech continue missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: print " %25s allocated %6.2f RP -- unlockable items: %s " % (element.tech, element.allocation, unlocked_items) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s " % (element.tech, element.allocation, missing_prereqs, unlocked_items) print # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() == 1) or ((fo.currentTurn() < 5) and (len(research_queue_list) == 0)): research_index = get_research_index() new_tech = TechsListsAI.sparse_galaxy_techs(research_index) if galaxy_is_sparse else TechsListsAI.primary_meta_techs(research_index) print "Empire %s (%d) is selecting research index %d" % (empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs+research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: print "Error: desired tech '%s' appears to not exist" % tech continue missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs+[tech]) cum_cost = 0 print " Enqueued Tech: %20s \t\t %8s \t %s" % ("Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % (name, this_cost, cum_cost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc() if foAI.foAIstate.aggression <= fo.aggression.cautious: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if def_tech not in research_queue_list[:5] and not tech_is_complete(def_tech): res = fo.issueEnqueueTechOrder(def_tech, min(3, len(research_queue_list))) print "Empire is very defensive, so attempted to fast-track %s, got result %d" % (def_tech, res) if False and foAI.foAIstate.aggression >= fo.aggression.aggressive: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list: insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list)-10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list: insert_idx = min(insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete(cc_tech): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) msg = "Empire is very aggressive, so attempted to fast-track %s, got result %d" % (cc_tech, res) if report_adjustments: chat_human(msg) else: print msg print"" generate_default_research_order() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" # coveredTechs = new_tech+completed_techs for tname in [tn for tn in alltechs if tn not in tech_base]: print tname elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(foAI.foAIstate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = foAI.foAIstate.colonisablePlanetIDs.items()[0][1] if len(foAI.foAIstate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = foAI.foAIstate.colonisableOutpostIDs.items()[0][1] need_improved_scouting = (best_colony_site_score < 150 or best_outpost_site_score < 200) if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]) and ( tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1+num_techs_accelerated]) and ( tech_is_complete("CON_METRO_INFRA")): for supply_tech in [_s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech)]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % (supply_tech, res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_GAL_INFRA"): num_techs_accelerated += 1 if ("CON_GAL_INFRA" not in research_queue_list[:1+num_techs_accelerated]) and ( tech_is_complete("PRO_SINGULAR_GEN")): res = fo.issueEnqueueTechOrder("CON_GAL_INFRA", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_GAL_INFRA", res) if report_adjustments: chat_human(msg) else: print msg else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete("SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2+num_techs_accelerated] and tech_is_complete("PRO_FUSION_GEN"): if "CON_ORBITAL_CON" not in research_queue_list[:1+num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ("CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (ColonisationAI.gotRuins and not tech_is_complete("LRN_XENOARCH") and foAI.foAIstate.aggression >= fo.aggression.typical): if "LRN_ARTIF_MINDS" in research_queue_list: insert_idx = 7 + research_queue_list.index("LRN_ARTIF_MINDS") elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in ["LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE"]: if not tech_is_complete(xenoTech) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 msg = "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d" % (xenoTech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_SENTIENT_AUTOMATION", "PRO_SENTIENT_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_SENTIENT_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_SENTIENT_AUTOMATION"]), ("PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", ["PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I"]), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [0, 1, 2]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: print "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s" % (move_tech, target_slot, target_index, num_techs_accelerated) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: res = fo.issueEnqueueTechOrder(move_tech, target_index) msg = "Research: To prioritize %s, have advanced %s to slot %d" % (tech, move_tech, target_index) if report_adjustments: chat_human(msg) else: print msg target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if ColonisationAI.got_ast: insert_idx = num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index("GRO_SYMBIOTIC_BIO") ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % (ast_tech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = (1 + insert_idx) if "LRN_FORCE_FIELD" not in research_queue_list else max(1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1) for ast_tech in ["SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS"]: if not tech_is_complete(ast_tech) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % (ast_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() if ColonisationAI.got_gg and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = 0 if "PRO_FUSION_GEN" not in research_queue_list else (1 + research_queue_list.index("PRO_FUSION_GEN")) forcefields_idx = 0 if "LRN_FORCE_FIELD" not in research_queue_list else (1 + research_queue_list.index("LRN_FORCE_FIELD")) insert_idx = max(fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx+1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 msg = "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d" % ("PRO_ORBITAL_GEN", res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and (not got_xeno_gen) and foAI.foAIstate.aggression >= fo.aggression.cautious: most_adequate = 0 for specName in ColonisationAI.empire_colonizers: environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max(most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if xg_tech not in research_queue_list[:1+num_techs_accelerated] and not tech_is_complete(xg_tech): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 msg = "Empire has poor colonizers, so attempted to fast-track %s, got result %d" % (xg_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in ColonisationAI.empire_species: this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break if (foAI.foAIstate.aggression > fo.aggression.cautious) and (empire.population() > ([300, 100][got_telepathy])): insert_idx = num_techs_accelerated for dt_ech in ["LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT"]: if dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(dt_ech): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" msg = fmt_str % (dt_ech, res, resource_production, empire.population(), fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if (foAI.foAIstate.aggression > fo.aggression.cautious) and (ColonisationAI.empire_status.get('researchers', 0) >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete(qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d" % (qnTech, res, fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and foAI.foAIstate.aggression > fo.aggression.cautious and not tech_is_complete(AIDependencies.PRO_SINGULAR_GEN) and tech_is_complete(AIDependencies.PRO_SOL_ORB_GEN)): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(AIDependencies.PRO_SINGULAR_GEN) sing_tech_list = [pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req)] sing_tech_list += [AIDependencies.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated+1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 msg = "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d" % (singTech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list] if len(missing_prereqs) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx-18))
def generate_research_orders(): """generate research orders""" report_adjustments = False empire = fo.getEmpire() empire_id = empire.empireID enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) galaxy_is_sparse = ColonisationAI.galaxy_is_sparse() print "Research Queue Management:" resource_production = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n" % resource_production print "Techs researched and available for use:" completed_techs = sorted(list(get_completed_techs())) tlist = completed_techs + 3 * [" "] tlines = zip(tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s" % tline print # # report techs currently at head of research queue # research_queue = empire.researchQueue research_queue_list = get_research_queue_techs() inProgressTechs.clear() tech_turns_left = {} if research_queue_list: print "Techs currently at head of Research Queue:" for element in list(research_queue)[:10]: tech_turns_left[element.tech] = element.turnsLeft if element.allocation > 0.0: inProgressTechs[element.tech] = True this_tech = fo.getTech(element.tech) if not this_tech: print "Error: can't retrieve tech ", element.tech continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in completed_techs ] # unlocked_items = [(uli.name, uli.type) for uli in this_tech.unlocked_items] unlocked_items = [uli.name for uli in this_tech.unlockedItems] if not missing_prereqs: print " %25s allocated %6.2f RP -- unlockable items: %s " % ( element.tech, element.allocation, unlocked_items) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s " % ( element.tech, element.allocation, missing_prereqs, unlocked_items) print # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn() == 1) or ((fo.currentTurn() < 5) and (len(research_queue_list) == 0)): research_index = get_research_index() new_tech = TechsListsAI.sparse_galaxy_techs( research_index ) if galaxy_is_sparse else TechsListsAI.primary_meta_techs( research_index) print "Empire %s (%d) is selecting research index %d" % ( empire.name, empire_id, research_index) # techs_to_enqueue = (set(new_tech)-(set(completed_techs)|set(research_queue_list))) techs_to_enqueue = new_tech[:] tech_base = set(completed_techs + research_queue_list) techs_to_add = [] for tech in techs_to_enqueue: if tech not in tech_base: this_tech = fo.getTech(tech) if this_tech is None: print "Error: desired tech '%s' appears to not exist" % tech continue missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq not in tech_base ] techs_to_add.extend(missing_prereqs + [tech]) tech_base.update(missing_prereqs + [tech]) cum_cost = 0 print " Enqueued Tech: %20s \t\t %8s \t %s" % ("Name", "Cost", "CumulativeCost") for name in techs_to_add: try: enqueue_res = fo.issueEnqueueTechOrder(name, -1) if enqueue_res == 1: this_tech = fo.getTech(name) this_cost = 0 if this_tech: this_cost = this_tech.researchCost(empire_id) cum_cost += this_cost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % ( name, this_cost, cum_cost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc( ) if foAI.foAIstate.aggression <= fo.aggression.cautious: research_queue_list = get_research_queue_techs() def_techs = TechsListsAI.defense_techs_1() for def_tech in def_techs: if def_tech not in research_queue_list[: 5] and not tech_is_complete( def_tech): res = fo.issueEnqueueTechOrder( def_tech, min(3, len(research_queue_list))) print "Empire is very defensive, so attempted to fast-track %s, got result %d" % ( def_tech, res) if False and foAI.foAIstate.aggression >= fo.aggression.aggressive: # with current stats of Conc Camps, disabling this fast-track research_queue_list = get_research_queue_techs() if "CON_CONC_CAMP" in research_queue_list: insert_idx = min(40, research_queue_list.index("CON_CONC_CAMP")) else: insert_idx = max(0, min(40, len(research_queue_list) - 10)) if "SHP_DEFLECTOR_SHIELD" in research_queue_list: insert_idx = min( insert_idx, research_queue_list.index("SHP_DEFLECTOR_SHIELD")) for cc_tech in ["CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if cc_tech not in research_queue_list[:insert_idx + 1] and not tech_is_complete( cc_tech): res = fo.issueEnqueueTechOrder(cc_tech, insert_idx) msg = "Empire is very aggressive, so attempted to fast-track %s, got result %d" % ( cc_tech, res) if report_adjustments: chat_human(msg) else: print msg print "" generate_default_research_order() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" # coveredTechs = new_tech+completed_techs for tname in [tn for tn in alltechs if tn not in tech_base]: print tname elif fo.currentTurn() > 100: generate_default_research_order() research_queue_list = get_research_queue_techs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged got_ggg_tech = tech_is_complete("PRO_ORBITAL_GEN") got_sym_bio = tech_is_complete("GRO_SYMBIOTIC_BIO") got_xeno_gen = tech_is_complete("GRO_XENO_GENETICS") # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup # # Supply range and detection range if False: # disabled for now, otherwise just to help with cold-folding / organization if len(foAI.foAIstate.colonisablePlanetIDs) == 0: best_colony_site_score = 0 else: best_colony_site_score = foAI.foAIstate.colonisablePlanetIDs.items( )[0][1] if len(foAI.foAIstate.colonisableOutpostIDs) == 0: best_outpost_site_score = 0 else: best_outpost_site_score = foAI.foAIstate.colonisableOutpostIDs.items( )[0][1] need_improved_scouting = (best_colony_site_score < 150 or best_outpost_site_score < 200) if need_improved_scouting: if not tech_is_complete("CON_ORBITAL_CON"): num_techs_accelerated += 1 if ("CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_FUSION_GEN") or ("PRO_FUSION_GEN" in research_queue_list[:1 + num_techs_accelerated])): res = fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_CONTGRAV_ARCH"): num_techs_accelerated += 1 if ("CON_CONTGRAV_ARCH" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("CON_METRO_INFRA")): for supply_tech in [ _s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if not tech_is_complete(_s_tech) ]: res = fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( supply_tech, res) if report_adjustments: chat_human(msg) else: print msg elif not tech_is_complete("CON_GAL_INFRA"): num_techs_accelerated += 1 if ("CON_GAL_INFRA" not in research_queue_list[:1 + num_techs_accelerated] ) and (tech_is_complete("PRO_SINGULAR_GEN")): res = fo.issueEnqueueTechOrder("CON_GAL_INFRA", num_techs_accelerated) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_GAL_INFRA", res) if report_adjustments: chat_human(msg) else: print msg else: pass research_queue_list = get_research_queue_techs() # could add more supply tech if False and not tech_is_complete( "SPY_DETECT_2"): # disabled for now, detect2 num_techs_accelerated += 1 if "SPY_DETECT_2" not in research_queue_list[:2 + num_techs_accelerated] and tech_is_complete( "PRO_FUSION_GEN" ): if "CON_ORBITAL_CON" not in research_queue_list[:1 + num_techs_accelerated]: res = fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: co_idx = research_queue_list.index("CON_ORBITAL_CON") res = fo.issueEnqueueTechOrder("SPY_DETECT_2", co_idx + 1) msg = "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d" % ( "CON_ORBITAL_CON", res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() # # check to accelerate xeno_arch if True: # just to help with cold-folding / organization if (ColonisationAI.gotRuins and not tech_is_complete("LRN_XENOARCH") and foAI.foAIstate.aggression >= fo.aggression.typical): if "LRN_ARTIF_MINDS" in research_queue_list: insert_idx = 7 + research_queue_list.index("LRN_ARTIF_MINDS") elif "GRO_SYMBIOTIC_BIO" in research_queue_list: insert_idx = research_queue_list.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in research_queue_list[:insert_idx]: for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN", "LRN_ALGO_ELEGANCE" ]: if not tech_is_complete( xenoTech ) and xenoTech not in research_queue_list[:(insert_idx + 4)]: res = fo.issueEnqueueTechOrder(xenoTech, insert_idx) num_techs_accelerated += 1 msg = "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d" % ( xenoTech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() if False and not enemies_sighted: # curently disabled # params = [ (tech, gate, target_slot, add_tech_list), ] params = [ ("GRO_XENO_GENETICS", "PRO_EXOBOTS", "PRO_EXOBOTS", ["GRO_GENETIC_MED", "GRO_XENO_GENETICS"]), ("PRO_EXOBOTS", "PRO_SENTIENT_AUTOMATION", "PRO_SENTIENT_AUTOMATION", ["PRO_EXOBOTS"]), ("PRO_SENTIENT_AUTOMATION", "PRO_NANOTECH_PROD", "PRO_NANOTECH_PROD", ["PRO_SENTIENT_AUTOMATION"]), ("PRO_INDUSTRY_CENTER_I", "GRO_SYMBIOTIC_BIO", "GRO_SYMBIOTIC_BIO", ["PRO_ROBOTIC_PROD", "PRO_FUSION_GEN", "PRO_INDUSTRY_CENTER_I"]), ("GRO_SYMBIOTIC_BIO", "SHP_ORG_HULL", "SHP_ZORTRIUM_PLATE", ["GRO_SYMBIOTIC_BIO"]), ] for (tech, gate, target_slot, add_tech_list) in params: if tech_is_complete(tech): break if tech_turns_left.get(gate, 0) not in [ 0, 1, 2 ]: # needs to exclude -1, the flag for no predicted completion continue if target_slot in research_queue_list: target_index = 1 + research_queue_list.index(target_slot) else: target_index = num_techs_accelerated for move_tech in add_tech_list: print "for tech %s, target_slot %s, target_index:%s ; num_techs_accelerated:%s" % ( move_tech, target_slot, target_index, num_techs_accelerated) if tech_is_complete(move_tech): continue if target_index <= num_techs_accelerated: num_techs_accelerated += 1 if move_tech not in research_queue_list[:1 + target_index]: res = fo.issueEnqueueTechOrder(move_tech, target_index) msg = "Research: To prioritize %s, have advanced %s to slot %d" % ( tech, move_tech, target_index) if report_adjustments: chat_human(msg) else: print msg target_index += 1 # # check to accelerate asteroid or GG tech if True: # just to help with cold-folding / organization if ColonisationAI.got_ast: insert_idx = num_techs_accelerated if "GRO_SYMBIOTIC_BIO" not in research_queue_list else research_queue_list.index( "GRO_SYMBIOTIC_BIO") ast_tech = "PRO_MICROGRAV_MAN" if not (tech_is_complete(ast_tech) or ast_tech in research_queue_list[:(1 + insert_idx)]): res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % ( ast_tech, res) if report_adjustments: chat_human(msg) else: print msg research_queue_list = get_research_queue_techs() elif tech_is_complete("SHP_ZORTRIUM_PLATE"): insert_idx = ( 1 + insert_idx ) if "LRN_FORCE_FIELD" not in research_queue_list else max( 1 + insert_idx, research_queue_list.index("LRN_FORCE_FIELD") - 1) for ast_tech in [ "SHP_ASTEROID_HULLS", "SHP_IMPROVED_ENGINE_COUPLINGS" ]: if not tech_is_complete( ast_tech ) and ast_tech not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder(ast_tech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Asteroids: plan to colonize an asteroid belt, so attempted to fast-track %s , got result %d" % ( ast_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() if ColonisationAI.got_gg and not tech_is_complete("PRO_ORBITAL_GEN"): fusion_idx = 0 if "PRO_FUSION_GEN" not in research_queue_list else ( 1 + research_queue_list.index("PRO_FUSION_GEN")) forcefields_idx = 0 if "LRN_FORCE_FIELD" not in research_queue_list else ( 1 + research_queue_list.index("LRN_FORCE_FIELD")) insert_idx = max( fusion_idx, forcefields_idx) if enemies_sighted else fusion_idx if "PRO_ORBITAL_GEN" not in research_queue_list[:insert_idx + 1]: res = fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN", insert_idx) num_techs_accelerated += 1 msg = "GasGiant: plan to colonize a gas giant, so attempted to fast-track %s, got result %d" % ( "PRO_ORBITAL_GEN", res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: # just to help with cold-folding / organization if got_ggg_tech and got_sym_bio and ( not got_xeno_gen ) and foAI.foAIstate.aggression >= fo.aggression.cautious: most_adequate = 0 for specName in ColonisationAI.empire_colonizers: environs = {} this_spec = fo.getSpecies(specName) if not this_spec: continue for ptype in [ fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids ]: environ = this_spec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) most_adequate = max( most_adequate, len(environs.get(fo.planetEnvironment.adequate, []))) if most_adequate == 0: insert_idx = num_techs_accelerated for xg_tech in ["GRO_XENO_GENETICS", "GRO_GENETIC_ENG"]: if xg_tech not in research_queue_list[:1 + num_techs_accelerated] and not tech_is_complete( xg_tech): res = fo.issueEnqueueTechOrder(xg_tech, insert_idx) num_techs_accelerated += 1 msg = "Empire has poor colonizers, so attempted to fast-track %s, got result %d" % ( xg_tech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate distrib thought if True: # just to help with cold-folding / organization if not tech_is_complete("LRN_DISTRIB_THOUGHT"): got_telepathy = False for specName in ColonisationAI.empire_species: this_spec = fo.getSpecies(specName) if this_spec and ("TELEPATHIC" in list(this_spec.tags)): got_telepathy = True break if (foAI.foAIstate.aggression > fo.aggression.cautious) and (empire.population() > ([300, 100][got_telepathy])): insert_idx = num_techs_accelerated for dt_ech in [ "LRN_PHYS_BRAIN", "LRN_TRANSLING_THT", "LRN_PSIONICS", "LRN_DISTRIB_THOUGHT" ]: if dt_ech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( dt_ech): res = fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" msg = fmt_str % (dt_ech, res, resource_production, empire.population(), fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # check to accelerate quant net if False: # disabled for now, otherwise just to help with cold-folding / organization if (foAI.foAIstate.aggression > fo.aggression.cautious) and ( ColonisationAI.empire_status.get('researchers', 0) >= 40): if not tech_is_complete("LRN_QUANT_NET"): insert_idx = num_techs_accelerated # TODO determine min target slot if reenabling for qnTech in ["LRN_NDIM_SUBSPACE", "LRN_QUANT_NET"]: if qnTech not in research_queue_list[:insert_idx + 2] and not tech_is_complete( qnTech): res = fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 insert_idx += 1 msg = "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d" % ( qnTech, res, fo.currentTurn()) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: # just to help with cold-folding / organization if (fo.currentTurn() > 50 and len(AIstate.empireStars.get(fo.starType.blackHole, [])) != 0 and foAI.foAIstate.aggression > fo.aggression.cautious and not tech_is_complete(AIDependencies.PRO_SINGULAR_GEN) and tech_is_complete(AIDependencies.PRO_SOL_ORB_GEN)): # sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(AIDependencies.PRO_SINGULAR_GEN) sing_tech_list = [ pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empire_id) if not tech_is_complete(pre_req) ] sing_tech_list += [AIDependencies.PRO_SINGULAR_GEN] for singTech in sing_tech_list: if singTech not in research_queue_list[:num_techs_accelerated + 1]: res = fo.issueEnqueueTechOrder(singTech, num_techs_accelerated) num_techs_accelerated += 1 msg = "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d" % ( singTech, res) print msg if report_adjustments: chat_human(msg) research_queue_list = get_research_queue_techs() # # if got deathray from Ruins, remove most prereqs from queue if True: # just to help with cold-folding / organization if tech_is_complete("SHP_WEAPON_4_1"): this_tech = fo.getTech("SHP_WEAPON_4_1") if this_tech: missing_prereqs = [ preReq for preReq in this_tech.recursivePrerequisites(empire_id) if preReq in research_queue_list ] if len(missing_prereqs ) > 2: # leave plasma 4 and 3 if up to them already for preReq in missing_prereqs: # sorted(missing_prereqs, reverse=True)[2:] if preReq in research_queue_list: fo.issueDequeueTechOrder(preReq) research_queue_list = get_research_queue_techs() if "SHP_WEAPON_4_2" in research_queue_list: # (should be) idx = research_queue_list.index("SHP_WEAPON_4_2") fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx - 18))
def exclude_tech(tech_name): return ((not get_aistate().character.may_research_tech(tech_name)) or tech_name in TechsListsAI.unusable_techs() or tech_name in Dep.UNRESEARCHABLE_TECHS)
def generateResearchOrders_old(): "generate research orders" empire = fo.getEmpire() print "Research Queue Management:" print "" print "Techs researched and available for use:" completedTechs = getCompletedTechs() for techname in completedTechs: print " " + techname print"" print "Techs currently in Research Queue:" researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() for element in researchQueue: print " " + element.tech print "" # get the highest research priorities print "Research Queue Priorities:" researchPriorities = {} for priorityType in getAIPriorityResearchTypes(): researchPriorities[priorityType] = foAI.foAIstate.getPriority(priorityType) sortedPriorities = researchPriorities.items() sortedPriorities.sort(lambda x,y: cmp(x[1], y[1]), reverse=True) topPriority = -1 for evaluationPair in sortedPriorities: if topPriority < 0: topPriority = evaluationPair[0] print " ID|Score: " + str(evaluationPair) print " Top Research Queue Priority: " + str(topPriority) print "" if topPriority == AIPriorityType.PRIORITY_RESEARCH_LEARNING: primaryLearningTechs = TechsListsAI.primaryLearningTechsList() pLTsToEnqueue = (set(primaryLearningTechs)-(set(completedTechs)|set(researchQueueList))) if not pLTsToEnqueue: print "All primaryLearningTechs are enqueued or completed." print"" generateDefaultResearchOrders() else: for name in pLTsToEnqueue: fo.issueEnqueueTechOrder(name, -1) print " Enqueued Tech: " + name print"" generateDefaultResearchOrders() elif topPriority == AIPriorityType.PRIORITY_RESEARCH_GROWTH: primaryGroTechs = TechsListsAI.primaryGroTechsList() pGTsToEnqueue = (set(primaryGroTechs)-(set(completedTechs)|set(researchQueueList))) if not pGTsToEnqueue: print "All primaryGrowthTechs are enqueued or completed." print"" generateDefaultResearchOrders() else: for name in pGTsToEnqueue: fo.issueEnqueueTechOrder(name, -1) print " Enqueued Tech: " + name print "" generateDefaultResearchOrders() elif topPriority == AIPriorityType.PRIORITY_RESEARCH_PRODUCTION: generateDefaultResearchOrders() elif topPriority == AIPriorityType.PRIORITY_RESEARCH_CONSTRUCTION: generateDefaultResearchOrders() elif topPriority == AIPriorityType.PRIORITY_RESEARCH_ECONOMICS: generateDefaultResearchOrders() elif topPriority == AIPriorityType.PRIORITY_RESEARCH_SHIPS: primaryShipsTechs = TechsListsAI.primaryShipsTechsList() pSTsToEnqueue = (set(primaryShipsTechs)-(set(completedTechs)|set(researchQueueList))) if not pSTsToEnqueue: print "All primaryShipsTechs are enqueued or completed." generateDefaultResearchOrders() print "" else: for name in pSTsToEnqueue: fo.issueEnqueueTechOrder(name, -1) print " Enqueued Tech: " + name print "" generateDefaultResearchOrders()
def generateResearchOrders(): global inProgressTechs "generate research orders" universe=fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID print "Research Queue Management:" tRP = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n"%tRP print "Techs researched and available for use:" completedTechs = sorted(list(getCompletedTechs())) tlist = completedTechs+3*[" "] tlines = zip( tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s"%tline print"" researchQueueList = getResearchQueueTechs() if tRP >= 20 and foAI.foAIstate.aggression > fo.aggression.cautious: if (empire.getTechStatus("LRN_PSIONICS") != fo.techStatus.complete) and ( "LRN_PSIONICS" not in researchQueueList[:5] ) : for specName in ColonisationAI.empireSpecies: thisSpec=fo.getSpecies(specName) if thisSpec: if "TELEPATHIC" in list(thisSpec.tags): res=fo.issueEnqueueTechOrder("LRN_DISTRIB_THOUGHT", 0) res=fo.issueEnqueueTechOrder("LRN_PSIONICS", 0) break if len(foAI.foAIstate.colonisablePlanetIDs)==0: bestColonySiteScore = 0 else: bestColonySiteScore= foAI.foAIstate.colonisablePlanetIDs[0][1] if len(foAI.foAIstate.colonisableOutpostIDs)==0: bestOutpostSiteScore = 0 else: bestOutpostSiteScore= foAI.foAIstate.colonisableOutpostIDs[0][1] needImprovedScouting = ( bestColonySiteScore <150 or bestOutpostSiteScore < 200 ) if needImprovedScouting: if (empire.getTechStatus("CON_ORBITAL_CON") != fo.techStatus.complete): if ( "CON_ORBITAL_CON" not in researchQueueList[:2] ) and ((empire.getTechStatus("PRO_FUSION_GEN") == fo.techStatus.complete) or ( "PRO_FUSION_GEN" in researchQueueList[:1] )): res=fo.issueEnqueueTechOrder("CON_ORBITAL_CON", 1) print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%("CON_ORBITAL_CON", res) else: pass #could add more supply tech if (empire.getTechStatus("SPY_DETECT_2") != fo.techStatus.complete): if ( "SPY_DETECT_2" not in researchQueueList[:3] ) and (empire.getTechStatus("PRO_FUSION_GEN") == fo.techStatus.complete) : if ( "CON_ORBITAL_CON" not in researchQueueList[:2] ): res=fo.issueEnqueueTechOrder("SPY_DETECT_2", 1) else: CO_idx = researchQueueList.index( "CON_ORBITAL_CON") res=fo.issueEnqueueTechOrder("SPY_DETECT_2", CO_idx+1) print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%("CON_ORBITAL_CON", res) gotGGG = empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete gotSymBio = empire.getTechStatus("GRO_SYMBIOTIC_BIO") == fo.techStatus.complete gotXenoGen = empire.getTechStatus("GRO_XENO_GENETICS") == fo.techStatus.complete #assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if gotGGG and gotSymBio and (not gotXenoGen) and foAI.foAIstate.aggression >= fo.aggression.cautious: mostAdequate=0 for specName in ColonisationAI.empireColonizers: environs={} thisSpec = fo.getSpecies(specName) if not thisSpec: continue for ptype in [fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids]: environ=thisSpec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) mostAdequate = max(mostAdequate, len(environs.get( fo.planetEnvironment.adequate, []))) if mostAdequate==0: researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() for xgTech in [ "GRO_XENO_GENETICS", "GRO_GENETIC_ENG" ]: if xgTech not in researchQueueList[:2] and empire.getTechStatus(xgTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(xgTech, 0) print "Empire has poor colonizers, so attempted to fast-track %s, got result %d"%(xgTech, res) researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() inProgressTechs.clear() if researchQueueList: print "Techs currently at head of Research Queue:" for element in list(researchQueue)[:10]: if element.allocation > 0.0: inProgressTechs[element.tech]=True thisTech=fo.getTech(element.tech) missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in completedTechs] unlockedItems = [(uli.name, uli.type) for uli in thisTech.unlockedItems] if not missingPrereqs: print " %25s allocated %6.2f RP -- unlockable items: %s "%(element.tech, element.allocation, unlockedItems) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s "%(element.tech, element.allocation, missingPrereqs, unlockedItems) print "" if (fo.currentTurn()==1) or ((fo.currentTurn()<5) and (len(researchQueueList)==0) ): if foAI.foAIstate.aggression <=fo.aggression.typical: newtech = TechsListsAI.primaryMetaTechsList( index=empireID%2 ) else: newtech = TechsListsAI.primaryMetaTechsList( index=empireID%2 ) #pLTsToEnqueue = (set(newtech)-(set(completedTechs)|set(researchQueueList))) pLTsToEnqueue = newtech[:] techBase = set(completedTechs+researchQueueList) techsToAdd=[] for tech in pLTsToEnqueue: if (tech not in techBase): thisTech=fo.getTech(tech) if thisTech is None: print "Error: desired tech '%s' appears to not exist"%tech continue missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in techBase] techsToAdd.extend( missingPrereqs+[tech] ) techBase.update( missingPrereqs+[tech] ) cumCost=0 print " Enqueued Tech: %20s \t\t %8s \t %s"%("Name", "Cost", "CumulativeCost") for name in techsToAdd: try: enqueueRes = fo.issueEnqueueTechOrder(name, -1) if enqueueRes == 1: thisTech=fo.getTech(name) thisCost=0 if thisTech: thisCost = thisTech.researchCost(empireID) cumCost += thisCost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % ( name, thisCost, cumCost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc() if foAI.foAIstate.aggression <= fo.aggression.cautious: researchQueueList = getResearchQueueTechs() defTechs=TechsListsAI.defenseTechs1() for defTech in defTechs: if defTech not in researchQueueList[:5] and empire.getTechStatus(defTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(defTech, min(3, len(researchQueueList))) print "Empire is very defensive, so attempted to fast-track %s, got result %d"%(defTech, res) if foAI.foAIstate.aggression >= fo.aggression.aggressive: researchQueueList = getResearchQueueTechs() if "CON_CONC_CAMP" in researchQueueList: insertIdx = min(40, researchQueueList.index("CON_CONC_CAMP")) else: insertIdx=max(0, min(40, len(researchQueueList)-10)) if "SHP_ASTEROID_HULLS" in researchQueueList: insertIdx = min(insertIdx, researchQueueList.index("SHP_ASTEROID_HULLS")) for ccTech in [ "CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if ccTech not in researchQueueList[:insertIdx+1] and empire.getTechStatus(ccTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(ccTech, insertIdx) print "Empire is very aggressive, so attempted to fast-track %s, got result %d"%(ccTech, res) print"" generateDefaultResearchOrders() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" #coveredTechs = newtech+completedTechs for tname in [tn for tn in alltechs if tn not in techBase]: print tname elif fo.currentTurn() >100: generateDefaultResearchOrders() #researchQueueList = getResearchQueueTechs() if fo.currentTurn() >50 and len (AIstate.empireStars.get(fo.starType.blackHole, []))!=0 and foAI.foAIstate.aggression > fo.aggression.cautious: for singTech in [ "CON_ARCH_PSYCH", "CON_CONC_CAMP", "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"]: if (empire.getTechStatus(singTech) != fo.techStatus.complete) and ( singTech not in researchQueueList[:4]) : res=fo.issueEnqueueTechOrder(singTech,0) print "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d"%(singTech, res)
def generateResearchOrders(): "generate research orders" universe=fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID print "Research Queue Management:" tRP = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n"%tRP print "Techs researched and available for use:" completedTechs = sorted(list(getCompletedTechs())) tlist = completedTechs+3*[" "] tlines = zip( tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s"%tline print"" # # report techs currently at head of research queue # researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() inProgressTechs.clear() if researchQueueList: print "Techs currently at head of Research Queue:" for element in list(researchQueue)[:10]: if element.allocation > 0.0: inProgressTechs[element.tech]=True thisTech=fo.getTech(element.tech) if not thisTech: print "Error: can't retrieve tech ", element.tech continue missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in completedTechs] #unlockedItems = [(uli.name, uli.type) for uli in thisTech.unlockedItems] unlockedItems = [uli.name for uli in thisTech.unlockedItems] if not missingPrereqs: print " %25s allocated %6.2f RP -- unlockable items: %s "%(element.tech, element.allocation, unlockedItems) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s "%(element.tech, element.allocation, missingPrereqs, unlockedItems) print "" # # set starting techs, or after turn 100 add any additional default techs # if (fo.currentTurn()==1) or ((fo.currentTurn()<5) and (len(researchQueueList)==0) ): research_index = get_research_index() newtech = TechsListsAI.primary_meta_techs(index = research_index) print "Empire %s (%d) is selecting research index %d"%(empire.name, empireID, research_index) #pLTsToEnqueue = (set(newtech)-(set(completedTechs)|set(researchQueueList))) pLTsToEnqueue = newtech[:] techBase = set(completedTechs+researchQueueList) techsToAdd=[] for tech in pLTsToEnqueue: if (tech not in techBase): thisTech=fo.getTech(tech) if thisTech is None: print "Error: desired tech '%s' appears to not exist"%tech continue missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in techBase] techsToAdd.extend( missingPrereqs+[tech] ) techBase.update( missingPrereqs+[tech] ) cumCost=0 print " Enqueued Tech: %20s \t\t %8s \t %s"%("Name", "Cost", "CumulativeCost") for name in techsToAdd: try: enqueueRes = fo.issueEnqueueTechOrder(name, -1) if enqueueRes == 1: thisTech=fo.getTech(name) thisCost=0 if thisTech: thisCost = thisTech.researchCost(empireID) cumCost += thisCost print " Enqueued Tech: %20s \t\t %8.0f \t %8.0f" % ( name, thisCost, cumCost) else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc() if foAI.foAIstate.aggression <= fo.aggression.cautious: researchQueueList = getResearchQueueTechs() defTechs = TechsListsAI.defense_techs_1() for defTech in defTechs: if defTech not in researchQueueList[:5] and empire.getTechStatus(defTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(defTech, min(3, len(researchQueueList))) print "Empire is very defensive, so attempted to fast-track %s, got result %d"%(defTech, res) if False and foAI.foAIstate.aggression >= fo.aggression.aggressive: #with current stats of Conc Camps, disabling this fast-track researchQueueList = getResearchQueueTechs() if "CON_CONC_CAMP" in researchQueueList: insertIdx = min(40, researchQueueList.index("CON_CONC_CAMP")) else: insertIdx=max(0, min(40, len(researchQueueList)-10)) if "SHP_DEFLECTOR_SHIELD" in researchQueueList: insertIdx = min(insertIdx, researchQueueList.index("SHP_DEFLECTOR_SHIELD")) for ccTech in [ "CON_ARCH_PSYCH", "CON_CONC_CAMP"]: if ccTech not in researchQueueList[:insertIdx+1] and empire.getTechStatus(ccTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(ccTech, insertIdx) print "Empire is very aggressive, so attempted to fast-track %s, got result %d"%(ccTech, res) print"" generateDefaultResearchOrders() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" #coveredTechs = newtech+completedTechs for tname in [tn for tn in alltechs if tn not in techBase]: print tname elif fo.currentTurn() >100: generateDefaultResearchOrders() researchQueueList = getResearchQueueTechs() num_techs_accelerated = 1 # will ensure leading tech doesn't get dislodged gotGGG = empire.getTechStatus("PRO_ORBITAL_GEN") == fo.techStatus.complete gotSymBio = empire.getTechStatus("GRO_SYMBIOTIC_BIO") == fo.techStatus.complete gotXenoGen = empire.getTechStatus("GRO_XENO_GENETICS") == fo.techStatus.complete # # Consider accelerating techs; priority is # Supply/Detect range # xeno arch # ast / GG # gro xeno gen # distrib thought # quant net # pro sing gen # death ray 1 cleanup # # Supply range and detection range if True: #just to help with cold-folding / organization if len(foAI.foAIstate.colonisablePlanetIDs)==0: bestColonySiteScore = 0 else: bestColonySiteScore= foAI.foAIstate.colonisablePlanetIDs[0][1] if len(foAI.foAIstate.colonisableOutpostIDs)==0: bestOutpostSiteScore = 0 else: bestOutpostSiteScore= foAI.foAIstate.colonisableOutpostIDs[0][1] needImprovedScouting = ( bestColonySiteScore <150 or bestOutpostSiteScore < 200 ) if needImprovedScouting: if (empire.getTechStatus("CON_ORBITAL_CON") != fo.techStatus.complete): if ( "CON_ORBITAL_CON" not in researchQueueList[:1 + num_techs_accelerated] ) and ( (empire.getTechStatus("PRO_FUSION_GEN") == fo.techStatus.complete) or ( "PRO_FUSION_GEN" in researchQueueList[:1+num_techs_accelerated] )): res=fo.issueEnqueueTechOrder("CON_ORBITAL_CON", num_techs_accelerated) num_techs_accelerated += 1 print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%("CON_ORBITAL_CON", res) elif (empire.getTechStatus("CON_CONTGRAV_ARCH") != fo.techStatus.complete): if ( "CON_CONTGRAV_ARCH" not in researchQueueList[:1+num_techs_accelerated] ) and ((empire.getTechStatus("CON_METRO_INFRA") == fo.techStatus.complete)): for supply_tech in [_s_tech for _s_tech in ["CON_ARCH_MONOFILS", "CON_CONTGRAV_ARCH"] if (empire.getTechStatus(_s_tech) != fo.techStatus.complete)]: res=fo.issueEnqueueTechOrder(supply_tech, num_techs_accelerated) num_techs_accelerated += 1 print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%(supply_tech, res) elif (empire.getTechStatus("CON_GAL_INFRA") != fo.techStatus.complete): if ( "CON_GAL_INFRA" not in researchQueueList[:1+num_techs_accelerated] ) and ((empire.getTechStatus("PRO_SINGULAR_GEN") == fo.techStatus.complete)): res=fo.issueEnqueueTechOrder("CON_GAL_INFRA", num_techs_accelerated) num_techs_accelerated += 1 print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%("CON_GAL_INFRA", res) else: pass researchQueueList = getResearchQueueTechs() #could add more supply tech if False and (empire.getTechStatus("SPY_DETECT_2") != fo.techStatus.complete): #disabled for now, detect2 if ( "SPY_DETECT_2" not in researchQueueList[:2+num_techs_accelerated] ) and (empire.getTechStatus("PRO_FUSION_GEN") == fo.techStatus.complete) : if ( "CON_ORBITAL_CON" not in researchQueueList[:1+num_techs_accelerated] ): res=fo.issueEnqueueTechOrder("SPY_DETECT_2", num_techs_accelerated) else: CO_idx = researchQueueList.index( "CON_ORBITAL_CON") res=fo.issueEnqueueTechOrder("SPY_DETECT_2", CO_idx+1) num_techs_accelerated += 1 print "Empire has poor colony/outpost prospects, so attempted to fast-track %s, got result %d"%("CON_ORBITAL_CON", res) researchQueueList = getResearchQueueTechs() # # check to accelerate xeno_arch if True: #just to help with cold-folding / organization if ColonisationAI.gotRuins and empire.getTechStatus("LRN_XENOARCH") != fo.techStatus.complete: if "LRN_ARTIF_MINDS" in researchQueueList: insert_idx = 7+ researchQueueList.index("LRN_ARTIF_MINDS") elif "GRO_SYMBIOTIC_BIO" in researchQueueList: insert_idx = researchQueueList.index("GRO_SYMBIOTIC_BIO") + 1 else: insert_idx = num_techs_accelerated if "LRN_XENOARCH" not in researchQueueList[:insert_idx]: for xenoTech in [ "LRN_XENOARCH", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN" , "LRN_ALGO_ELEGANCE"]: if (empire.getTechStatus(xenoTech) != fo.techStatus.complete) and ( xenoTech not in researchQueueList[:(insert_idx+4)]) : res=fo.issueEnqueueTechOrder(xenoTech,insert_idx) num_techs_accelerated += 1 print "ANCIENT_RUINS: have an ancient ruins, so attempted to fast-track %s to enable LRN_XENOARCH, got result %d"%(xenoTech, res) researchQueueList = getResearchQueueTechs() # # check to accelerate asteroid or GG tech if True: #just to help with cold-folding / organization if ColonisationAI.gotAst and empire.getTechStatus("SHP_ASTEROID_HULLS") != fo.techStatus.complete and ( ("SHP_ASTEROID_HULLS" not in researchQueueList[num_techs_accelerated])): #if needed but not top item, will block acceleration of pro_orb_gen if ("SHP_ASTEROID_HULLS" not in researchQueueList[:2+num_techs_accelerated]): if "GRO_SYMBIOTIC_BIO" in researchQueueList: insert_idx = 1+ researchQueueList.index("GRO_SYMBIOTIC_BIO") else: insert_idx = num_techs_accelerated for ast_tech in ["SHP_ASTEROID_HULLS", "PRO_MICROGRAV_MAN"]: if (empire.getTechStatus(ast_tech) != fo.techStatus.complete) and ( ast_tech not in researchQueueList[:insert_idx+2]) : res=fo.issueEnqueueTechOrder(ast_tech,insert_idx) num_techs_accelerated += 1 print "Asteroids: have colonized an asteroid belt, so attempted to fast-track %s , got result %d"%(ast_tech, res) researchQueueList = getResearchQueueTechs() elif ColonisationAI.gotGG and empire.getTechStatus("PRO_ORBITAL_GEN") != fo.techStatus.complete and ( "PRO_ORBITAL_GEN" not in researchQueueList[:3+num_techs_accelerated]): if "GRO_SYMBIOTIC_BIO" in researchQueueList: insert_idx = 1+ researchQueueList.index("GRO_SYMBIOTIC_BIO") else: insert_idx = num_techs_accelerated res=fo.issueEnqueueTechOrder("PRO_ORBITAL_GEN",insert_idx) num_techs_accelerated += 1 print "GasGiant: have colonized a gas giant, so attempted to fast-track %s, got result %d"%("PRO_ORBITAL_GEN", res) researchQueueList = getResearchQueueTechs() # # assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if True: #just to help with cold-folding / organization if gotGGG and gotSymBio and (not gotXenoGen) and foAI.foAIstate.aggression >= fo.aggression.cautious: mostAdequate=0 for specName in ColonisationAI.empireColonizers: environs={} thisSpec = fo.getSpecies(specName) if not thisSpec: continue for ptype in [fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids]: environ=thisSpec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) mostAdequate = max(mostAdequate, len(environs.get( fo.planetEnvironment.adequate, []))) if mostAdequate==0: insert_idx = num_techs_accelerated for xgTech in [ "GRO_XENO_GENETICS", "GRO_GENETIC_ENG" ]: if xgTech not in researchQueueList[:1+num_techs_accelerated] and empire.getTechStatus(xgTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(xgTech, insert_idx) num_techs_accelerated += 1 print "Empire has poor colonizers, so attempted to fast-track %s, got result %d"%(xgTech, res) researchQueueList = getResearchQueueTechs() # # check to accelerate distrib thought if True: #just to help with cold-folding / organization if (empire.getTechStatus("LRN_DISTRIB_THOUGHT") != fo.techStatus.complete): got_telepathy = False for specName in ColonisationAI.empireSpecies: thisSpec=fo.getSpecies(specName) if thisSpec and ("TELEPATHIC" in list(thisSpec.tags)): got_telepathy = True break if ((foAI.foAIstate.aggression > fo.aggression.cautious) and (empire.population() > ([300, 100][got_telepathy]))): insert_idx = num_techs_accelerated for dt_ech in [ "LRN_DISTRIB_THOUGHT", "LRN_PSIONICS", "LRN_TRANSLING_THT", "LRN_PHYS_BRAIN" ]: if dt_ech not in researchQueueList[:4+num_techs_accelerated] and empire.getTechStatus(dt_ech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(dt_ech, insert_idx) num_techs_accelerated += 1 fmt_str = "Empire has a telepathic race, so attempted to fast-track %s (got result %d)" fmt_str += " with current target_RP %.1f and current pop %.1f, on turn %d" print fmt_str%( dt_ech, res, tRP, empire.population(), fo.currentTurn()) researchQueueList = getResearchQueueTechs() # # check to accelerate quant net if True: #just to help with cold-folding / organization if (foAI.foAIstate.aggression > fo.aggression.cautious) and( ColonisationAI.empire_status.get('researchers', 0) >= 40 ): if (empire.getTechStatus("LRN_QUANT_NET") != fo.techStatus.complete): insert_idx = num_techs_accelerated for qnTech in [ "LRN_NDIM_SUBSPACE", "LRN_QUANT_NET" ]: if qnTech not in researchQueueList[:2+num_techs_accelerated] and empire.getTechStatus(qnTech) != fo.techStatus.complete: res=fo.issueEnqueueTechOrder(qnTech, insert_idx) num_techs_accelerated += 1 print "Empire has many researchers, so attempted to fast-track %s (got result %d) on turn %d"%(qnTech, res, fo.currentTurn()) researchQueueList = getResearchQueueTechs() # # if we own a blackhole, accelerate sing_gen and conc camp if True: #just to help with cold-folding / organization if ( fo.currentTurn() >50 and len (AIstate.empireStars.get(fo.starType.blackHole, []))!=0 and foAI.foAIstate.aggression > fo.aggression.cautious and (empire.getTechStatus(AIDependencies.sing_tech_name) != fo.techStatus.complete) ): #sing_tech_list = [ "LRN_GRAVITONICS" , "PRO_SINGULAR_GEN"] # formerly also "CON_ARCH_PSYCH", "CON_CONC_CAMP", sing_gen_tech = fo.getTech(AIDependencies.sing_tech_name) sing_tech_list = [pre_req for pre_req in sing_gen_tech.recursivePrerequisites(empireID) if (empire.getTechStatus(pre_req) != fo.techStatus.complete) ] sing_tech_list += [ AIDependencies.sing_tech_name ] for singTech in sing_tech_list: if ( singTech not in researchQueueList[:num_techs_accelerated+1 ]) : res=fo.issueEnqueueTechOrder(singTech,num_techs_accelerated) num_techs_accelerated += 1 print "have a black hole star outpost/colony, so attempted to fast-track %s, got result %d"%(singTech, res) researchQueueList = getResearchQueueTechs() # # if got deathray from Ruins, remove most prereqs from queue if True: #just to help with cold-folding / organization if empire.getTechStatus("SHP_WEAPON_4_1" ) == fo.techStatus.complete: thisTech=fo.getTech("SHP_WEAPON_4_1") if thisTech: missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq in researchQueueList] if len(missingPrereqs) > 2 : #leave plasma 4 and 3 if up to them already for preReq in missingPrereqs: #sorted(missingPrereqs, reverse=True)[2:] if preReq in researchQueueList: res = fo.issueDequeueTechOrder(preReq) if "SHP_WEAPON_4_2" in researchQueueList: #(should be) idx = researchQueueList.index("SHP_WEAPON_4_2") res=fo.issueEnqueueTechOrder("SHP_WEAPON_4_2", max(0, idx-15) ) researchQueueList = getResearchQueueTechs()
def exclude_tech(tech_name): return ((foAI.foAIstate.aggression < AIDependencies.TECH_EXCLUSION_MAP_1.get(tech_name, fo.aggression.invalid)) or (foAI.foAIstate.aggression > AIDependencies.TECH_EXCLUSION_MAP_2.get(tech_name, fo.aggression.maniacal)) or tech_name in TechsListsAI.unusable_techs())
def generateResearchOrders(): global inProgressTechs "generate research orders" universe=fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID print "Research Queue Management:" tRP = empire.resourceProduction(fo.resourceType.research) print "\nTotal Current Research Points: %.2f\n"%tRP print "Techs researched and available for use:" completedTechs = sorted(list(getCompletedTechs())) tlist = completedTechs+3*[" "] tlines = zip( tlist[0::3], tlist[1::3], tlist[2::3]) for tline in tlines: print "%25s %25s %25s"%tline print"" if tRP >= 20 and foAI.foAIstate.aggression > 1: researchQueueList = getResearchQueueTechs() if (empire.getTechStatus("LRN_PSIONICS") != fo.techStatus.complete) and ( "LRN_PSIONICS" not in researchQueueList[:5] ) : for specName in ColonisationAI.empireSpecies: thisSpec=fo.getSpecies(specName) if thisSpec: if "TELEPATHIC" in list(thisSpec.tags): res=fo.issueEnqueueTechOrder("LRN_DISTRIB_THOUGHT", 0) res=fo.issueEnqueueTechOrder("LRN_PSIONICS", 0) break gotSymBio = empire.getTechStatus("GRO_SYMBIOTIC_BIO") == fo.techStatus.complete gotXenoGen = empire.getTechStatus("GRO_XENO_GENETICS") == fo.techStatus.complete #assess if our empire has any non-lousy colonizers, & boost gro_xeno_gen if we don't if gotSymBio and (not gotXenoGen) and foAI.foAIstate.aggression!=0: mostAdequate=0 for specName in ColonisationAI.empireColonizers: environs={} thisSpec = fo.getSpecies(specName) if not thisSpec: continue for ptype in [fo.planetType.swamp, fo.planetType.radiated, fo.planetType.toxic, fo.planetType.inferno, fo.planetType.barren, fo.planetType.tundra, fo.planetType.desert, fo.planetType.terran, fo.planetType.ocean, fo.planetType.asteroids]: environ=thisSpec.getPlanetEnvironment(ptype) environs.setdefault(environ, []).append(ptype) mostAdequate = max(mostAdequate, len(environs.get( fo.planetEnvironment.adequate, []))) if mostAdequate==0: researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() if "GRO_XENO_GENETICS" not in researchQueueList[:2]: res=fo.issueEnqueueTechOrder("GRO_XENO_GENETICS", 0) print "Empire has poor colonizers, so attempted to fast-track GRO_XENO_GENETICS, got result %d"%res researchQueue = empire.researchQueue researchQueueList = getResearchQueueTechs() inProgressTechs.clear() if researchQueueList: print "Techs currently at head of Research Queue:" for element in list(researchQueue)[:10]: if element.allocation > 0.0: inProgressTechs[element.tech]=True thisTech=fo.getTech(element.tech) missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in completedTechs] unlockedItems = [(uli.name, uli.type) for uli in thisTech.unlockedItems] if not missingPrereqs: print " %25s allocated %6.2f RP -- unlockable items: %s "%(element.tech, element.allocation, unlockedItems) else: print " %25s allocated %6.2f RP -- missing preReqs: %s -- unlockable items: %s "%(element.tech, element.allocation, missingPrereqs, unlockedItems) print "" if fo.currentTurn()==1: newtech = TechsListsAI.primaryMetaTechsList() #pLTsToEnqueue = (set(newtech)-(set(completedTechs)|set(researchQueueList))) pLTsToEnqueue = newtech[:] techBase = set(completedTechs+researchQueueList) techsToAdd=[] for tech in pLTsToEnqueue: if (tech not in techBase): thisTech=fo.getTech(tech) if thisTech is None: continue missingPrereqs = [preReq for preReq in thisTech.recursivePrerequisites(empireID) if preReq not in techBase] techsToAdd.extend( missingPrereqs+[tech] ) techBase.update( missingPrereqs+[tech] ) for name in techsToAdd: try: enqueueRes = fo.issueEnqueueTechOrder(name, -1) if enqueueRes == 1: print " Enqueued Tech: " + name else: print " Error: failed attempt to enqueued Tech: " + name except: print " Error: failed attempt to enqueued Tech: " + name print " Error: exception triggered and caught: ", traceback.format_exc() print"" generateDefaultResearchOrders() print "\n\nAll techs:" alltechs = fo.techs() # returns names of all techs for tname in alltechs: print tname print "\n-------------------------------\nAll unqueued techs:" coveredTechs = newtech+completedTechs for tname in [tn for tn in alltechs if tn not in coveredTechs]: print tname elif fo.currentTurn() >50: generateDefaultResearchOrders()