示例#1
0
def convert_to_version(state, version):
    """Convert a savegame AIstate to the next version.

    :param dict state: savegame state, modified in function
    :param int version: Version to convert to
    """
    debug("Trying to convert savegame state to version %d..." % version)
    current_version = state.get("version", -1)
    debug("  Current version: %d" % current_version)
    if current_version == version:
        raise ConversionError("Can't convert AI savegame to the same compatibility version.")

    if current_version > version:
        raise ConversionError("Can't convert AI savegame to an older compatibility version.")

    if version != current_version + 1:
        raise ConversionError("Can't skip a compatibility version when converting AI savegame.")

    # Starting with version 3, we switched from pickle to json-style encoding
    # Do not try to load an older savegame even if it magically passed the encoder.
    if version <= 3:
        raise ConversionError("The AI savegame version is no longer supported.")

    if version == 4:
        del state['qualifyingOutpostBaseTargets']
        del state['qualifyingColonyBaseTargets']
        state['orbital_colonization_manager'] = ColonisationAI.OrbitalColonizationManager()

    if version == 5:
        state['last_turn_played'] = 0

    #   state["some_new_member"] = some_default_value
    #   del state["some_removed_member"]
    #   state["list_changed_to_set"] = set(state["list_changed_to_set"])

    debug("  All updates set. Setting new version number.")
    state["version"] = version
示例#2
0
    def __init__(self, aggression):
        # Do not allow to create AIstate instances with an invalid version number.
        if not hasattr(AIstate, 'version'):
            raise ConversionError("AIstate must have an integer version attribute for savegame compatibility")
        if not isinstance(AIstate.version, int):
            raise ConversionError("Version attribute of AIstate must be an integer!")
        if AIstate.version < 0:
            raise ConversionError("AIstate savegame compatibility version must be a positive integer!")

        # need to store the version explicitly as the class variable "version" is only stored in the
        # self.__class__.__dict__ while we only pickle the object (i.e. self.__dict__ )
        self.version = AIstate.version

        # Debug info
        # unique id for game
        self.uid = self.generate_uid(first=True)
        # unique ids for turns.  {turn: uid}
        self.turn_uids = {}

        # see AIstate docstring re importance of int cast for aggression
        self._aggression = int(aggression)

        # 'global' (?) variables
        self.colonisablePlanetIDs = odict()
        self.colonisableOutpostIDs = odict()  #
        self.__aiMissionsByFleetID = {}
        self.__shipRoleByDesignID = {}
        self.__fleetRoleByID = {}
        self.diplomatic_logs = {}
        self.__priorityByType = {}

        # initialize home system knowledge
        universe = fo.getUniverse()
        empire = fo.getEmpire()
        self.empireID = empire.empireID
        homeworld = universe.getPlanet(empire.capitalID)
        self.__origin_home_system_id = homeworld.systemID if homeworld else INVALID_ID
        self.visBorderSystemIDs = {self.__origin_home_system_id}
        self.visInteriorSystemIDs = set()
        self.exploredSystemIDs = set()
        self.unexploredSystemIDs = {self.__origin_home_system_id}
        self.fleetStatus = {}  # keys: 'sysID', 'nships', 'rating'
        # systemStatus keys:
        # 'name', 'neighbors' (sysIDs), '2jump_ring' (sysIDs), '3jump_ring', '4jump_ring', 'enemy_ship_count',
        # 'fleetThreat', 'planetThreat', 'monsterThreat' (specifically, immobile nonplanet threat), 'totalThreat',
        # 'localEnemyFleetIDs', 'neighborThreat', 'max_neighbor_threat', 'jump2_threat' (up to 2 jumps away),
        # 'jump3_threat', 'jump4_threat', 'regional_threat', 'myDefenses' (planet rating), 'myfleets',
        # 'myFleetsAccessible'(not just next desitination), 'myFleetRating', 'my_neighbor_rating' (up to 1 jump away),
        # 'my_jump2_rating', 'my_jump3_rating', my_jump4_rating', 'local_fleet_threats',
        # 'regional_fleet_threats' <== these are only for mobile fleet threats
        self.systemStatus = {}
        self.needsEmergencyExploration = []
        self.newlySplitFleets = {}
        self.militaryRating = 0
        self.shipCount = 4
        self.misc = {}  # Keys: "enemies_sighted" (dict[turn: list[fleetIDs]]),
        #                       "observed_empires" (set[enemy empire IDs]),
        #                       "ReassignedFleetMissions" (list[FleetMissions])
        self.orbital_colonization_manager = ColonisationAI.OrbitalColonizationManager()
        self.qualifyingTroopBaseTargets = {}
        # TODO: track on a per-empire basis
        self.__empire_standard_enemy = CombatRatingsAI.default_ship_stats().get_stats(hashable=True)
        self.empire_standard_enemy_rating = 0  # TODO: track on a per-empire basis
        self.character = create_character(aggression, self.empireID)
        self.last_turn_played = 0