diff options
Diffstat (limited to 'diplomacy/engine/power.py')
-rw-r--r-- | diplomacy/engine/power.py | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/diplomacy/engine/power.py b/diplomacy/engine/power.py index 1fe282b..c3826e6 100644 --- a/diplomacy/engine/power.py +++ b/diplomacy/engine/power.py @@ -15,6 +15,7 @@ # with this program. If not, see <https://www.gnu.org/licenses/>. # ============================================================================== """ Power + - Contains the power object representing a power in the game """ from copy import deepcopy @@ -28,33 +29,36 @@ from diplomacy.utils.constants import OrderSettings class Power(Jsonable): """ Power Class - Properties: - - abbrev - Contains the abbrev of the power (usually the first letter of the power name) (e.g. 'F' for FRANCE) - - adjust - List of pending adjustment orders - (e.g. ['A PAR B', 'A PAR R MAR', 'A MAR D', 'WAIVE']) - - centers - Contains the list of supply centers currently controlled by the power ['MOS', 'SEV', 'STP', 'WAR'] - - civil_disorder - Boolean flag to indicate that the power has been put in CIVIL_DISORDER (e.g. True or False) - - controller - Sorted dictionary mapping timestamp to controller (either dummy or a user ID) who takes - control of power at this timestamp. - - game - Contains a reference to the game object - - goner - Boolean to indicate that this power doesn't control any SCs any more (e.g. True or False) - - homes - Contains a list of homes supply centers (where you can build) - e.g. ['PAR', 'MAR', ... ] or None if empty - - influence - Contains a list of locations influenced by this power - Note: To influence a location, the power must have visited it last. - e.g ['PAR', 'MAR', ... ] - - name - Contains the name of the power - - orders - Contains a dictionary of units and their orders. - For NO_CHECK games, unit is 'ORDER 1', 'ORDER 2', ... - - e.g. {'A PAR': '- MAR' } or {'ORDER 1': 'A PAR - MAR', 'ORDER 2': '...', ... } - - Can also be {'REORDER 1': 'A PAR - MAR', 'INVALID 1': 'A PAR - MAR', ... } after validation - - retreats - Contains the list of units that need to retreat with their possible retreat locations - (e.g. {'A PAR': ['MAR', 'BER']}) - - role - Power type (observer, omniscient, player or server power). - Either the power name (for a player power) or a value in diplomacy.utils.strings.ALL_ROLE_TYPES - - tokens - Only for server power: set of tokens of current power controlled (if not None). - - units - Contains the list of units (e.g. ['A PAR', 'A MAR', ...] - - vote - Only for omniscient, player and server power: power vote ('yes', 'no' or 'neutral'). + Properties: + + - **abbrev** - Contains the abbrev of the power (i.e. the first letter of the power name) (e.g. 'F' for FRANCE) + - **adjust** - List of pending adjustment orders + (e.g. ['A PAR B', 'A PAR R MAR', 'A MAR D', 'WAIVE']) + - **centers** - Contains the list of supply centers currently controlled by the power ['MOS', 'SEV', 'STP'] + - **civil_disorder** - Bool flag to indicate that the power has been put in CIVIL_DISORDER (e.g. True or False) + - **controller** - Sorted dictionary mapping timestamp to controller (either dummy or a user ID) who takes + control of power at this timestamp. + - **game** - Contains a reference to the game object + - **goner** - Boolean to indicate that this power doesn't control any SCs any more (e.g. True or False) + - **homes** - Contains a list of homes supply centers (where you can build) + e.g. ['PAR', 'MAR', ... ] or None if empty + - **influence** - Contains a list of locations influenced by this power + Note: To influence a location, the power must have visited it last. + e.g ['PAR', 'MAR', ... ] + - **name** - Contains the name of the power (e.g. 'FRANCE') + - **orders** - Contains a dictionary of units and their orders. + For NO_CHECK games, unit is 'ORDER 1', 'ORDER 2', ... + + - e.g. {'A PAR': '- MAR' } or {'ORDER 1': 'A PAR - MAR', 'ORDER 2': '...', ... } + - Can also be {'REORDER 1': 'A PAR - MAR', 'INVALID 1': 'A PAR - MAR', ... } after validation + + - **retreats** - Contains the list of units that need to retreat with their possible retreat locations + (e.g. {'A PAR': ['MAR', 'BER']}) + - **role** - Power type (observer, omniscient, player or server power). + Either the power name (for a player power) or a value in diplomacy.utils.strings.ALL_ROLE_TYPES + - **tokens** - Only for server power: set of tokens of current power controlled (if not None). + - **units** - Contains the list of units (e.g. ['A PAR', 'A MAR', ...] + - **vote** - Only for omniscient, player and server power: power vote ('yes', 'no' or 'neutral'). """ __slots__ = ['game', 'name', 'abbrev', 'adjust', 'centers', 'units', 'influence', 'homes', 'retreats', 'goner', 'civil_disorder', 'orders', 'role', 'controller', 'vote', @@ -128,9 +132,7 @@ class Power(Jsonable): return text def __deepcopy__(self, memo): - """ Fast deep copy implementation - - (Not setting the game object) - """ + """ Fast deep copy implementation (**not setting the game object**) """ cls = self.__class__ result = cls.__new__(cls) @@ -145,6 +147,7 @@ class Power(Jsonable): def reinit(self, include_flags=6): """ Performs a reinitialization of some of the parameters + :param include_flags: Bit mask to indicate which params to reset (bit 1 = orders, 2 = persistent, 4 = transient) :return: None @@ -187,6 +190,7 @@ class Power(Jsonable): @staticmethod def compare(power_1, power_2): """ Comparator object - Compares two Power objects + :param power_1: The first Power object to compare :param power_2: The second Power object to compare :return: 1 if self is greater, -1 if other is greater, 0 if they are equal @@ -199,6 +203,7 @@ class Power(Jsonable): def initialize(self, game): """ Initializes a game and resets home, centers and units + :param game: The game to use for initialization :type game: diplomacy.Game """ @@ -233,6 +238,7 @@ class Power(Jsonable): def merge(self, other_power): """ Transfer all units, centers, and homes of the other_power to this power + :param other_power: The other power (will be empty after the merge) """ # Regular units @@ -291,12 +297,14 @@ class Power(Jsonable): def is_dummy(self): """ Indicates if the power is a dummy + :return: Boolean flag to indicate if the power is a dummy """ return self.controller.last_value() == strings.DUMMY def is_eliminated(self): """ Returns a flag to show if player is eliminated + :return: If the current power is eliminated """ # Not eliminated if has units left @@ -310,6 +318,7 @@ class Power(Jsonable): def moves_submitted(self): """ Returns a boolean to indicate if moves has been submitted + :return: 1 if not in Movement phase, or orders submitted, or no more units lefts """ if self.game.phase_type != 'M': @@ -321,35 +330,37 @@ class Power(Jsonable): # ============================================================== def is_observer_power(self): - """ Return True if this power is an observer power. """ + """ (Network Method) Return True if this power is an observer power. """ return self.role == strings.OBSERVER_TYPE def is_omniscient_power(self): - """ Return True if this power is an omniscient power. """ + """ (Network Method) Return True if this power is an omniscient power. """ return self.role == strings.OMNISCIENT_TYPE def is_player_power(self): - """ Return True if this power is a player power. """ + """ (Network Method) Return True if this power is a player power. """ return self.role == self.name def is_server_power(self): - """ Return True if this power is a server power. """ + """ (Network Method) Return True if this power is a server power. """ return self.role == strings.SERVER_TYPE def is_controlled(self): - """ Return True if this power is controlled. """ + """ (Network Method) Return True if this power is controlled. """ return self.controller.last_value() != strings.DUMMY def does_not_wait(self): - """ Return True if this power does not wait (ie. if we could already process orders of this power). """ + """ (Network Method) Return True if this power does not wait + (ie. if we could already process orders of this power). + """ return self.order_is_set and not self.wait def update_controller(self, username, timestamp): - """ Update controller with given username and timestamp. """ + """ (Network Method) Update controller with given username and timestamp. """ self.controller.put(timestamp, username) def set_controlled(self, username): - """ Control power with given username. Username may be None (meaning no controller). """ + """ (Network Method) Control power with given username. Username may be None (meaning no controller). """ if username is None or username == strings.DUMMY: if self.controller.last_value() != strings.DUMMY: self.controller.put(common.timestamp_microseconds(), strings.DUMMY) @@ -363,15 +374,15 @@ class Power(Jsonable): raise DiplomacyException('Power already controlled by someone else. Kick previous controller before.') def get_controller(self): - """ Return current power controller name ('dummy' if power is not controlled). """ + """ (Network Method) Return current power controller name ('dummy' if power is not controlled). """ return self.controller.last_value() def get_controller_timestamp(self): - """ Return timestamp when current controller took control of this power. """ + """ (Network Method) Return timestamp when current controller took control of this power. """ return self.controller.last_key() def is_controlled_by(self, username): - """ Return True if this power is controlled by given username. """ + """ (Network Method) Return True if this power is controlled by given username. """ if username == constants.PRIVATE_BOT_USERNAME: # Bot is connected if power is dummy and has some associated tokens. return self.is_dummy() and bool(self.tokens) @@ -380,16 +391,16 @@ class Power(Jsonable): # Server-only methods. def has_token(self, token): - """ Return True if this power has given token. """ + """ (Server Method) Return True if this power has given token. """ assert self.is_server_power() return token in self.tokens def add_token(self, token): - """ Add given token to this power. """ + """ (Server Method) Add given token to this power. """ assert self.is_server_power() self.tokens.add(token) def remove_tokens(self, tokens): - """ Remove sequence of tokens from this power. """ + """ (Server Method) Remove sequence of tokens from this power. """ assert self.is_server_power() self.tokens.difference_update(tokens) |