def _handle_shell_input(self, message): print('>', message, end='') out, err = self._interpreter.eval(message) if out: chat_human(self._formatter.white(out)) if err: chat_human(self._formatter.red(err))
def test_calc_max_pop(): """ Verify AI calculation of max population by comparing it with actual client queried values. This function may be called in debug mode in a running game and will compare the actual target population meters on all planets owned by this AI with the predicted maximum population. Any mismatch will be reported in chat. """ from freeorion_tools import chat_human chat_human("Verifying calculation of ColonisationAI.calc_max_pop()") universe = fo.getUniverse() for spec_name, planets in get_empire_planets_by_species().items(): species = fo.getSpecies(spec_name) for pid in planets: planet = universe.getPlanet(pid) detail = [] predicted = calc_max_pop(planet, species, detail) actual = planet.initialMeterValue(fo.meterType.targetPopulation) if actual != predicted: error( "Predicted pop of %.2f on %s but actually is %.2f; Details: %s" % (predicted, planet, actual, "\n".join(detail)) ) chat_human("Finished verification of ColonisationAI.calc_max_pop()")
def _handle_start(self, message): try: player_id = int(message[5:].strip()) except ValueError: if self._ai_should_respond(): message = self._formatter.red( "Invalid empire id, please input valid number") chat_human(message) self._handle_help() return # This message is not for that AI if player_id != fo.playerID(): return self._start_debug_mode()
def resumeLoadedGame(saved_state_string): # pylint: disable=invalid-name """Called by client to when resume a loaded game.""" debug("Resuming loaded game") if saved_state_string == "NO_STATE_YET" and fo.currentTurn() == 1: info("AI given uninitialized state-string to resume from on turn 1.") info( "Assuming post-universe-generation autosave before any orders were sent " "and behaving as if a new game was started.") return startNewGame() 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 aistate = None if saved_state_string == "NOT_SET_BY_CLIENT_TYPE": info("AI assigned to empire previously run by human.") chat_human( "We have been assigned an empire previously run by a human player. We can manage this." ) elif saved_state_string == "": error( "AI given empty state-string to resume from. " "AI can continue but behaviour may be different from the previous session." ) else: try: # loading saved state aistate = load_aistate(saved_state_string) except Exception as e: error( "Failed to load the AIstate from the savegame: %s" " AI can continue but behaviour may be different from the previous session.", e, exc_info=True, ) if aistate is None: info("Creating new ai state due to failed load.") aistate = create_new_aistate(_choose_aggression()) aistate.session_start_cleanup() _pre_game_start(fo.getEmpire().empireID)
def _start_debug_mode(self): self._debug_mode = True start_message = [ self._entering_debug_message, "Print %s to exit." % self._formatter.blue('stop'), "Local variables:", ] variables_description = self._interpreter.set_locals() for var, name in variables_description: start_message.append(' %s%s%s' % ( self._formatter.underline(self._formatter.yellow(var)), ' ' * (3 - len(var)), # cannot use normal formatting because of tags name)) chat_human("\n".join(self._formatter.white(x) for x in start_message))
def _handle_help(self): if not self._ai_should_respond(): return help_message = [ self._formatter.white("Chat commands:"), self._formatter.white( " " + self._formatter.underline(self._formatter.blue('start <id>')) + ": start debug for selected empire"), ] for player_id in fo.allPlayerIDs(): if not fo.playerIsHost(player_id): help_message.append(self._get_empire_string(player_id)) self._formatter.white( " " + self._formatter.underline(self._formatter.blue('stop')) + ": stop debug"), chat_human('\n'.join(help_message))
def handle_debug_chat(sender, message): global debug_mode human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] is_debug_chat = False if message == ENTERING_DEBUG_MESSAGE: is_debug_chat = True if sender != human_id: return is_debug_chat # don't chat with bots elif message == 'stop': is_debug_chat = True if debug_mode: chat_human("exiting debug mode") debug_mode = False elif debug_mode: is_debug_chat = True out, err = shell(message) if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): is_debug_chat = True try: player_id = int(message[5:].strip()) except ValueError as e: print e chat_human(str(e)) return True if player_id == fo.playerID(): debug_mode = True # add some variables to scope lines = ['import FreeOrionAI as foAI', 'ai = foAI.foAIstate', 'u = fo.getUniverse()', 'e = fo.getEmpire()' ] shell(';'.join(lines)) # Notify all players this AI entering debug mode fo.sendChatMessage(-1, WHITE % ENTERING_DEBUG_MESSAGE) chat_human(WHITE % "Print 'stop' to exit.") chat_human(WHITE % " Local vars: <u>u</u>(universe), <u>e</u>(empire), <u>ai</u>(aistate)") elif message == 'help': is_debug_chat = True if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human(WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire") chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human(' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} empire_name={0.name}</rgba> player_name={1}'.format(fo.getEmpire(fo.playerEmpireID(player)), fo.playerName(player))) return is_debug_chat
def handle_debug_chat(sender, message): global debug_mode human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] is_debug_chat = False if message == ENTERING_DEBUG_MESSAGE: is_debug_chat = True if sender != human_id: return is_debug_chat # don't chat with bots elif message == 'stop': is_debug_chat = True if debug_mode: chat_human("exiting debug mode") debug_mode = False elif debug_mode: print('>', message, end='') is_debug_chat = True out, err = [x.strip('\n') for x in shell(message)] if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): is_debug_chat = True try: player_id = int(message[5:].strip()) except ValueError as e: error(e) chat_human(str(e)) return True if player_id == fo.playerID(): debug_mode = True initial_code = [ 'from aistate_interface import get_aistate', ] # add some variables to scope: (name, help text, value) scopes_variable = ( ('ai', 'aistate', 'get_aistate()'), ('u', 'universe', 'fo.getUniverse()'), ('e', 'empire', 'fo.getEmpire()'), ) for var, _, code in scopes_variable: initial_code.append('%s = %s' % (var, code)) shell(';'.join(initial_code)) variable_template = '<u><rgba 255 255 0 255>%s</rgba></u>%s %s' variables = (variable_template % (var, ' ' * (3 - len(var)), name) for var, name, _ in scopes_variable) chat_human(WHITE % "%s\n" "Print <rgba 255 255 0 255>'stop'</rgba> to exit.\n" "Local variables:\n" " %s" % (ENTERING_DEBUG_MESSAGE, '\n '.join(variables))) elif message == 'help': is_debug_chat = True if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human(WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire") chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human(' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} empire_name={0.name}</rgba> player_name={1}'.format(fo.getEmpire(fo.playerEmpireID(player)), fo.playerName(player))) return is_debug_chat
def find_path_with_resupply( start: int, target: int, fleet_id: int, minimum_fuel_at_target: int = 0, mission_type_override: Optional[MissionType] = None ) -> PathInformation: """ :param start: start system id :param target: target system id :param fleet_id: fleet to find the path for :param minimum_fuel_at_target: optional - if specified, only accept paths that leave the fleet with at least this much fuel left at the target system :param mission_type_override: optional - use the specified mission type, rather than the fleet's current mission type, for pathfinding routing choices :return: shortest possible path including resupply-detours in the form of system ids including both start and target system """ universe = fo.getUniverse() fleet = universe.getFleet(fleet_id) if not fleet: return None empire = fo.getEmpire() supplied_systems = set(empire.fleetSupplyableSystemIDs) start_fuel = fleet.maxFuel if start in supplied_systems else fleet.fuel # We have 1 free jump from supplied system into unsupplied systems. # Thus, the target system must be at most maxFuel + 1 jumps away # in order to reach the system under standard conditions. # In some edge cases, we may have more supply here than what the # supply graph suggests. For example, we could have recently refueled # in a system that is now blockaded by an enemy or we have found # the refuel special. target_distance_from_supply = -min(get_system_supply(target), 0) if (fleet.maxFuel + 1 < (target_distance_from_supply + minimum_fuel_at_target) and universe.jumpDistance(start, target) > (start_fuel - minimum_fuel_at_target)): # can't possibly reach this system with the required fuel return None mission_type = (mission_type_override if mission_type_override is not None else get_aistate().get_fleet_mission(fleet_id)) may_travel_starlane_func = _STARLANE_TRAVEL_FUNC_MAP.get( mission_type, _more_careful_travel_starlane_func) path_info = find_path_with_resupply_generic( start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target, may_travel_starlane_func=may_travel_starlane_func) if not _DEBUG_CHAT: return path_info if may_travel_starlane_func != _may_travel_anywhere: risky_path = find_path_with_resupply_generic( start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target) if path_info and may_travel_starlane_func == _risky_travel_starlane_func: safest_path = find_path_with_resupply_generic( start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target, may_travel_starlane_func=_more_careful_travel_starlane_func) if safest_path and path_info.distance < safest_path.distance: message = "(Scout?) Fleet %d chose somewhat risky path %s instead of safe path %s" % ( fleet_id, _info_string(path_info), _info_string(risky_path)) chat_human(message) if path_info and risky_path and risky_path.distance < path_info.distance: message = "Fleet %d chose safer path %s instead of risky path %s" % ( fleet_id, _info_string(path_info), _info_string(risky_path)) chat_human(message) return path_info
def handle_debug_chat(sender, message): global debug_mode human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] is_debug_chat = False if message == ENTERING_DEBUG_MESSAGE: is_debug_chat = True if sender != human_id: return is_debug_chat # don't chat with bots elif message == 'stop': is_debug_chat = True if debug_mode: chat_human("exiting debug mode") debug_mode = False elif debug_mode: print '>', message, is_debug_chat = True out, err = [x.strip('\n') for x in shell(message)] if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): is_debug_chat = True try: player_id = int(message[5:].strip()) except ValueError as e: print e chat_human(str(e)) return True if player_id == fo.playerID(): debug_mode = True initial_code = [ 'import FreeOrionAI as foAI', ] # add some variables to scope: (name, help text, value) scopes_variable = ( ('ai', 'aistate', 'foAI.foAIstate'), ('u', 'universe', 'fo.getUniverse()'), ('e', 'empire', 'fo.getEmpire()'), ) for var, _, code in scopes_variable: initial_code.append('%s = %s' % (var, code)) shell(';'.join(initial_code)) variable_template = '<u><rgba 255 255 0 255>%s</rgba></u>%s %s' variables = (variable_template % (var, ' ' * (3 - len(var)), name) for var, name, _ in scopes_variable) chat_human(WHITE % "%s\n" "Print <rgba 255 255 0 255>'stop'</rgba> to exit.\n" "Local variables:\n" " %s" % (ENTERING_DEBUG_MESSAGE, '\n '.join(variables))) elif message == 'help': is_debug_chat = True if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human( WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire" ) chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human( ' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} empire_name={0.name}</rgba> player_name={1}' .format(fo.getEmpire(fo.playerEmpireID(player)), fo.playerName(player))) return is_debug_chat
def find_path_with_resupply(start, target, fleet_id, minimum_fuel_at_target=0, mission_type_override=None): """ :param start: start system id :type start: int :param target: target system id :type target: int :param fleet_id: fleet to find the path for :type fleet_id: int :param minimum_fuel_at_target: optional - if specified, only accept paths that leave the fleet with at least this much fuel left at the target system :type minimum_fuel_at_target: int :param mission_type_override: optional - use the specified mission type, rather than the fleet's current mission type, for pathfinding routing choices :type mission_type_override: MissionType :return: shortest possible path including resupply-detours in the form of system ids including both start and target system :rtype: path_information """ universe = fo.getUniverse() fleet = universe.getFleet(fleet_id) if not fleet: return None empire = fo.getEmpire() supplied_systems = set(empire.fleetSupplyableSystemIDs) start_fuel = fleet.maxFuel if start in supplied_systems else fleet.fuel # We have 1 free jump from supplied system into unsupplied systems. # Thus, the target system must be at most maxFuel + 1 jumps away # in order to reach the system under standard conditions. # In some edge cases, we may have more supply here than what the # supply graph suggests. For example, we could have recently refueled # in a system that is now blockaded by an enemy or we have found # the refuel special. target_distance_from_supply = -min(state.get_system_supply(target), 0) if (fleet.maxFuel + 1 < (target_distance_from_supply + minimum_fuel_at_target) and universe.jumpDistance(start, target) > (start_fuel - minimum_fuel_at_target)): # can't possibly reach this system with the required fuel return None mission_type = (mission_type_override if mission_type_override is not None else foAI.foAIstate.get_fleet_mission(fleet_id)) may_travel_starlane_func = _STARLANE_TRAVEL_FUNC_MAP.get(mission_type, _more_careful_travel_starlane_func) path_info = find_path_with_resupply_generic(start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target, may_travel_starlane_func=may_travel_starlane_func) if not _DEBUG_CHAT: return path_info if may_travel_starlane_func != _may_travel_anywhere: risky_path = find_path_with_resupply_generic(start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target) if path_info and may_travel_starlane_func == _risky_travel_starlane_func: safest_path = find_path_with_resupply_generic(start, target, start_fuel, fleet.maxFuel, lambda s: s in supplied_systems, minimum_fuel_at_target, may_travel_starlane_func=_more_careful_travel_starlane_func) if safest_path and path_info.distance < safest_path.distance: message = "(Scout?) Fleet %d chose somewhat risky path %s instead of safe path %s" % ( fleet_id, _info_string(path_info), _info_string(risky_path)) chat_human(message) if path_info and risky_path and risky_path.distance < path_info.distance: message = "Fleet %d chose safer path %s instead of risky path %s" % ( fleet_id, _info_string(path_info), _info_string(risky_path)) chat_human(message) return path_info
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 _chat_printer(message: Any): return chat_human(message, send_to_logs=False)
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 handle_debug_chat(sender, message): human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] if sender != human_id: pass # don't chat with bots elif message == 'stop': global debug_mode debug_mode = False if ais[0] == fo.playerID(): chat_human("exiting debug mode") elif debug_mode: out, err = shell(message) if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): try: player_id = int(message[5:].strip()) except ValueError as e: print e return if player_id == fo.playerID(): global debug_mode debug_mode = True # add some variables to scope lines = ['import FreeOrionAI as foAI', 'ai = foAI.foAIstate', 'u = fo.getUniverse()', 'e = fo.getEmpire()' ] shell(';'.join(lines)) chat_human(WHITE % "Entering debug mode. print 'stop' to exit.") chat_human(WHITE % " Local vars: <u>u</u>(universe), <u>e</u>(empire), <u>ai</u>(aistate)") elif message == 'help': if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human(WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire") chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human(' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} name={0.name}</rgba>'.format(fo.getEmpire(player)))
def handle_debug_chat(sender, message): human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] if sender != human_id: pass # don't chat with bots elif message == 'stop': global debug_mode debug_mode = False if ais[0] == fo.playerID(): chat_human("exiting debug mode") elif debug_mode: out, err = shell(message) if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): try: player_id = int(message[5:].strip()) except ValueError as e: print e return if player_id == fo.playerID(): global debug_mode debug_mode = True # add some variables to scope lines = [ 'import FreeOrionAI as foAI', 'ai = foAI.foAIstate', 'u = fo.getUniverse()', 'e = fo.getEmpire()' ] shell(';'.join(lines)) chat_human(WHITE % "Entering debug mode. print 'stop' to exit.") chat_human( WHITE % " Local vars: <u>u</u>(universe), <u>e</u>(empire), <u>ai</u>(aistate)" ) elif message == 'help': if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human( WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire" ) chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human( ' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} name={0.name}</rgba>' .format(fo.getEmpire(player)))
def handle_debug_chat(sender, message): global debug_mode human_id = [x for x in fo.allPlayerIDs() if fo.playerIsHost(x)][0] ais = [x for x in fo.allPlayerIDs() if not fo.playerIsHost(x)] is_debug_chat = False if message == ENTERING_DEBUG_MESSAGE: is_debug_chat = True if sender != human_id: return is_debug_chat # don't chat with bots elif message == 'stop': is_debug_chat = True if debug_mode: chat_human("exiting debug mode") debug_mode = False elif debug_mode: is_debug_chat = True out, err = shell(message) if out: chat_human(WHITE % out) if err: chat_human(RED % err) elif message.startswith('start'): is_debug_chat = True try: player_id = int(message[5:].strip()) except ValueError as e: print e chat_human(str(e)) return True if player_id == fo.playerID(): debug_mode = True # add some variables to scope lines = [ 'import FreeOrionAI as foAI', 'ai = foAI.foAIstate', 'u = fo.getUniverse()', 'e = fo.getEmpire()' ] shell(';'.join(lines)) # Notify all players this AI entering debug mode fo.sendChatMessage(-1, WHITE % ENTERING_DEBUG_MESSAGE) chat_human(WHITE % "Print 'stop' to exit.") chat_human( WHITE % " Local vars: <u>u</u>(universe), <u>e</u>(empire), <u>ai</u>(aistate)" ) elif message == 'help': is_debug_chat = True if ais[0] == fo.playerID(): chat_human(WHITE % "Chat commands:") chat_human( WHITE % " <u><rgba 0 255 255 255>start id</rgba></u>: start debug for selected empire" ) chat_human(WHITE % " <u><rgba 0 255 255 255>stop</rgba></u>: stop debug") chat_human(WHITE % "Empire ids:") for player in fo.allPlayerIDs(): if not fo.playerIsHost(player): chat_human( ' <rgba {0.colour.r} {0.colour.g} {0.colour.b} {0.colour.a}>id={0.empireID} empire_name={0.name}</rgba> player_name={1}' .format(fo.getEmpire(fo.playerEmpireID(player)), fo.playerName(player))) return is_debug_chat
def _handle_stop(self): chat_human(self._exit_debug_message) self._debug_mode = False