def test_get_centers(): """ Test - get centers """ game = Game() centers = game.get_centers() assert centers['AUSTRIA'] == ['BUD', 'TRI', 'VIE'] assert centers['ENGLAND'] == ['EDI', 'LON', 'LVP'] assert centers['FRANCE'] == ['BRE', 'MAR', 'PAR'] assert centers['GERMANY'] == ['BER', 'KIE', 'MUN'] assert centers['ITALY'] == ['NAP', 'ROM', 'VEN'] assert centers['RUSSIA'] == ['MOS', 'SEV', 'STP', 'WAR'] assert centers['TURKEY'] == ['ANK', 'CON', 'SMY'] assert game.get_centers('AUSTRIA') == ['BUD', 'TRI', 'VIE'] assert game.get_centers('ENGLAND') == ['EDI', 'LON', 'LVP'] assert game.get_centers('FRANCE') == ['BRE', 'MAR', 'PAR'] assert game.get_centers('GERMANY') == ['BER', 'KIE', 'MUN'] assert game.get_centers('ITALY') == ['NAP', 'ROM', 'VEN'] assert game.get_centers('RUSSIA') == ['MOS', 'SEV', 'STP', 'WAR'] assert game.get_centers('TURKEY') == ['ANK', 'CON', 'SMY'] # Making sure we got a copy, and not a direct game reference austria = game.get_power('AUSTRIA') austria.centers.remove('BUD') centers_2 = game.get_centers() assert centers['AUSTRIA'] == ['BUD', 'TRI', 'VIE'] assert centers_2['AUSTRIA'] == ['TRI', 'VIE']
def test_clear_units(): """ Tests - Clear units """ game = Game() game.clear_units() for power in game.powers.values(): assert not power.units assert not game.error
def test_clear_centers(): """ Tests - Clear centers """ game = Game() game.clear_centers() for power in game.powers.values(): assert not power.centers assert not game.error
def to_saved_game_format(game): """ Converts a game to a standardized JSON format :param game: game to convert. :return: A game in the standard JSON format used to saved game (returned object is a dictionary) :type game: Game """ # Get phase history. phases = Game.get_phase_history(game) # Add current game phase. phases.append(Game.get_phase_data(game)) # Filter rules. rules = [rule for rule in game.rules if rule not in RULES_TO_SKIP] # Extend states fields. phases_to_dict = [phase.to_dict() for phase in phases] for phase_dct in phases_to_dict: phase_dct['state']['game_id'] = game.game_id phase_dct['state']['map'] = game.map_name phase_dct['state']['rules'] = rules # Building saved game return { 'id': game.game_id, 'map': game.map_name, 'rules': rules, 'phases': phases_to_dict }
def add(self, game): """ Add given game. :param game: a NetworkGame object. :type game: diplomacy.client.network_game.NetworkGame """ assert self.game_id == game.game_id if Game.is_player_game(game): if game.role in self.games: raise exceptions.DiplomacyException( 'Power name %s already in game instances set.' % game.role) elif Game.is_observer_game(game): if self.current_observer_type is not None: raise exceptions.DiplomacyException( 'Previous special game %s must be removed before adding new one.' % self.current_observer_type) self.current_observer_type = game.role else: assert Game.is_omniscient_game(game) if self.current_observer_type is not None: raise exceptions.DiplomacyException( 'Previous special game %s must be removed before adding new one.' % self.current_observer_type) self.current_observer_type = game.role self.games[game.role] = game
def on_omniscient_updated(game, notification): """ Manage notification OmniscientUpdated. :param game: game associated to received notification. :param notification: received notification. :type game: diplomacy.client.network_game.NetworkGame :type notification: notifications.OmniscientUpdated """ assert not Game.is_player_game(game) if Game.is_observer_game(game): assert notification.grade_update == strings.PROMOTE assert notification.game.is_omniscient_game() else: assert notification.grade_update == strings.DEMOTE assert notification.game.is_observer_game() # Save client game channel and invalidate client game. channel = game.channel game.channel = None channel.game_id_to_instances[notification.game_id].remove(game.role) # Create a new client game with previous client game channel game sent by server. new_game = NetworkGame(channel, notification.game) new_game.notification_callbacks.update({ key: value.copy() for key, value in game.notification_callbacks.items() }) new_game.data = game.data channel.game_id_to_instances[notification.game_id].add(new_game)
def on_power_wait_flag(game, notification): """ Manage notification PowerWaitFlag. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.PowerWaitFlag """ Game.set_wait(game, notification.power_name, notification.wait)
def on_power_orders_update(game, notification): """ Manage notification PowerOrdersUpdate. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.PowerOrdersUpdate """ Game.set_orders(game, notification.power_name, notification.orders)
def on_game_status_update(game, notification): """ Manage notification GameStatusUpdate. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.GameStatusUpdate """ Game.set_status(game, notification.status)
def on_game_message_received(game, notification): """ Manage notification GameMessageReceived.. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.GameMessageReceived """ Game.add_message(game, notification.message)
def on_cleared_units(game, notification): """ Manage notification ClearedUnits. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.ClearedUnits """ Game.clear_units(game, notification.power_name)
def on_clear_units(context, response): """ Manage response for request ClearUnits. :param context: request context :param response: response received :return: None :type context: RequestFutureContext """ request = context.request # type: requests.ClearUnits Game.clear_units(context.game, request.power_name)
def on_set_game_status(context, response): """ Manage response for request SetGameStatus. :param context: request context :param response: response received :return: None :type context: RequestFutureContext """ request = context.request # type: requests.SetGameStatus Game.set_status(context.game, request.status)
def on_vote_updated(game, notification): """ Manage notification VoteUpdated (for omniscient game). :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.VoteUpdated """ assert Game.is_omniscient_game(game) for power_name, vote in notification.vote.items(): Game.get_power(game, power_name).vote = vote
def on_game_phase_update(game, notification): """ Manage notification GamePhaseUpdate. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.GamePhaseUpdate """ if notification.phase_data_type == strings.STATE_HISTORY: Game.extend_phase_history(game, notification.phase_data) else: game.set_phase_data(notification.phase_data)
def on_send_game_message(context, response): """ Manage response for request SendGameMessage. :param context: request context :param response: response received :return: None :type context: RequestFutureContext :type response: responses.DataTimeStamp """ request = context.request # type: requests.SendGameMessage message = request.message message.time_sent = response.data Game.add_message(context.game, message)
def on_get_phase_history(context, response): """ Manage response for request GetPhaseHistory. :param context: request context :param response: response received :return: a list of game states :type context: RequestFutureContext :type response: responses.DataGamePhases """ phase_history = response.data for game_phase in phase_history: # type: diplomacy.utils.game_phase_data.GamePhaseData Game.extend_phase_history(context.game, game_phase) return phase_history
def test_set_current_phase(): """ Tests - set current phase""" game = Game() power = game.get_power('FRANCE') power.units.remove('A PAR') game.set_current_phase('W1901A') game.clear_cache() assert game.get_current_phase() == 'W1901A' assert game.phase_type == 'A' assert 'A PAR B' in game.get_all_possible_orders()['PAR']
def on_set_orders(context, response): """ Manage response for request SetOrders. :param context: request context :param response: response received :return: None :type context: RequestFutureContext """ request = context.request # type: requests.SetOrders orders = request.orders if Game.is_player_game(context.game): assert context.game.power.name == context.request.game_role Game.set_orders(context.game, request.game_role, orders) else: Game.set_orders(context.game, request.power_name, orders)
def on_set_wait_flag(context, response): """ Manage response for request SetWaitFlag. :param context: request context :param response: response received :return: None :type context: RequestFutureContext """ request = context.request # type: requests.SetWaitFlag wait = request.wait if Game.is_player_game(context.game): assert context.game.power.name == context.request.game_role Game.set_wait(context.game, request.game_role, wait) else: Game.set_wait(context.game, request.power_name, wait)
def on_powers_controllers(game, notification): """ Manage notification PowersControllers. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.PowersControllers """ if Game.is_player_game(game) and notification.powers[ game.power.name] != game.power.get_controller(): # Player is now invalid. We just remove game from related channel. game.channel.game_id_to_instances[game.game_id].remove(game.power.name) else: # In any other case, update powers controllers. Game.update_powers_controllers(game, notification.powers, notification.timestamps)
def on_vote_count_updated(game, notification): """ Manage notification VoteCountUpdated (for observer game). :param game: game associated to received notification. :param notification: received notification. :type game: diplomacy.client.network_game.NetworkGame """ assert Game.is_observer_game(game)
def on_power_vote_updated(game, notification): """ Manage notification PowerVoteUpdated (for power game). :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame :type notification: diplomacy.communication.notifications.PowerVoteUpdated """ assert Game.is_player_game(game) game.power.vote = notification.vote
def on_game_deleted(game, notification): """ Manage notification GameDeleted. :param game: a Network game :param notification: notification received :type game: diplomacy.client.network_game.NetworkGame """ # We remove game from related channel. if Game.is_player_game(game): game.channel.game_id_to_instances[game.game_id].remove(game.power.name) else: game.channel.game_id_to_instances[game.game_id].remove_special()
def on_vote(context, response): """ Manage response for request VoteAboutDraw. :param context: request context :param response: response received :return: None :type context: RequestFutureContext """ request = context.request # type: requests.Vote vote = request.vote assert Game.is_player_game(context.game) assert context.game.power.name == context.request.game_role context.game.power.vote = vote
def test_result_history(): """ Test result history. """ short_phase_name = 'S1901M' game = Game() game.set_orders('FRANCE', ['A PAR - BUR', 'A MAR - BUR']) assert game.current_short_phase == short_phase_name game.process() assert game.current_short_phase == 'F1901M' phase_data = game.get_phase_from_history(short_phase_name) assert BOUNCE in phase_data.results['A PAR'] assert BOUNCE in phase_data.results['A MAR']
def from_saved_game_format(saved_game): """ Rebuilds a :class:`diplomacy.engine.game.Game` object from the saved game (python :class:`Dict`) saved_game is the dictionary. It can be built by calling json.loads(json_line). :param saved_game: The saved game exported from :meth:`to_saved_game_format` :type saved_game: Dict :rtype: diplomacy.engine.game.Game :return: The game object restored from the saved game """ game_id = saved_game.get('id', None) kwargs = {strings.MAP_NAME: saved_game.get('map', 'standard'), strings.RULES: saved_game.get('rules', [])} # Building game game = Game(game_id=game_id, **kwargs) phase_history = [] # Restoring every phase for phase_dct in saved_game.get('phases', []): phase_history.append(GamePhaseData.from_dict(phase_dct)) game.set_phase_data(phase_history, clear_history=True) # Returning game return game
def to_saved_game_format(game, output_path=None, output_mode='a'): """ Converts a game to a standardized JSON format :param game: game to convert. :param output_path: Optional path to file. If set, the json.dumps() of the saved_game is written to that file. :param output_mode: Optional. The mode to use to write to the output_path (if provided). Defaults to 'a' :return: A game in the standard format used to saved game, that can be converted to JSON for serialization :type game: diplomacy.engine.game.Game :type output_path: str | None, optional :type output_mode: str, optional :rtype: Dict """ phases = Game.get_phase_history(game) # Get phase history. phases.append(Game.get_phase_data(game)) # Add current game phase. rules = [rule for rule in game.rules if rule not in RULES_TO_SKIP] # Filter rules. # Extend states fields. phases_to_dict = [phase.to_dict() for phase in phases] for phase_dct in phases_to_dict: phase_dct['state']['game_id'] = game.game_id phase_dct['state']['map'] = game.map_name phase_dct['state']['rules'] = rules # Building saved game saved_game = {'id': game.game_id, 'map': game.map_name, 'rules': rules, 'phases': phases_to_dict} # Writing to disk if output_path: with open(output_path, output_mode) as output_file: output_file.write(json.dumps(saved_game) + '\n') # Returning return saved_game
def as_omniscient_game(self, for_username): """ Return an omniscient game data object copy of this game. """ game = Game.from_dict(self.to_dict()) game.message_history = self.get_message_history( strings.OMNISCIENT_TYPE) game.messages = self.get_messages(strings.OMNISCIENT_TYPE) game.phase_abbr = game.current_short_phase for power in game.powers.values(): # type: Power power.role = strings.OMNISCIENT_TYPE power.tokens.clear() game.role = strings.OMNISCIENT_TYPE game.controlled_powers = self.get_controlled_power_names(for_username) game.observer_level = self.get_observer_level(for_username) game.daide_port = self.server.get_daide_port( self.game_id) if self.server else None return game
def as_power_game(self, power_name): """ Return a player game data object copy of this game for given power name. """ for_username = self.get_power(power_name).get_controller() game = Game.from_dict(self.to_dict()) game.error = [] game.message_history = self.get_message_history(power_name) game.messages = self.get_messages(power_name) game.phase_abbr = game.current_short_phase related_power_names = self.get_related_power_names(power_name) for power in game.powers.values(): # type: Power power.role = power.name power.tokens.clear() if power.name not in related_power_names: power.vote = strings.NEUTRAL power.orders.clear() game.role = power_name game.controlled_powers = self.get_controlled_power_names(for_username) game.observer_level = self.get_observer_level(for_username) game.daide_port = self.server.get_daide_port( self.game_id) if self.server else None return game