diff --git a/NoPELib/player_settings.py b/NoPELib/player_settings.py index 3c0984e..c92cd38 100644 --- a/NoPELib/player_settings.py +++ b/NoPELib/player_settings.py @@ -8,28 +8,28 @@ Needs to handle modifying number of players import copy import json import logging +from pathlib import Path _log = logging.getLogger('NoPE-Lib') class PlayersManager: """ - Attribute: + Attributes: gameID (str): The gameID of the active game - Methods: save: """ defaultPlayerConfig = {"flags": [], "expansions": {}, "games": {}} - def __init__(self, gameID: str=None, activePlayers: list[str]=None, playersPath: str='./players.json', loggerID: str='Players'): + def __init__(self, gameID: str=None, activePlayers: list[str]=None, playersPath: str='./players.json', loggerID: str='PlayersManager'): """ Initialises a list of players. Args: gameID (str): The ID of the game used in the configuration file. - activePlayers (list of str): The names of the players that are playing + activePlayers (list of str): The names of the players that are playing. Defaults to none which includes all players. playersPath (str, optional): The path of the players.json file. Defaults to './players.json'. loggerID (str, optional): The ID used for logging. Defaults to 'Players'. """ @@ -37,15 +37,16 @@ class PlayersManager: # Store the arguments self._log = _log.getChild(loggerID) self._currentGameID = gameID - self._playersPath = playersPath - activePlayers = activePlayers if activePlayers is not None else [] + # Deal with the path + self._playersPath = Path(playersPath) # Get the config file - with open(playersPath, 'r') as f: + with open(self._playersPath, 'r') as f: self._cfg = json.load(f) # Create the players + activePlayers = activePlayers if activePlayers is not None else self._cfg["players"].keys() self._player_data = { - Player(name, game=None, **cfg) - for name, cfg in self._cfg["players"].items() + name: Player(name, self, **player_cfg) + for name, player_cfg in self._cfg["players"].items() if name in activePlayers } @@ -55,9 +56,9 @@ class PlayersManager: If the player wasn't active, make them active. If the player didn't exist previously, create a default config and make them active. """ - if playerName not in self._cfg: + if playerName not in self._cfg["players"]: # Create the brand new player - self._cfg[playerName] = copy.deepcopy(self.defaultPlayerConfig) + self._cfg["players"][playerName] = copy.deepcopy(self.defaultPlayerConfig) newPlayer = Player(playerName, self, **self._cfg["players"][playerName]) # Make the player active self._player_data[playerName] = newPlayer @@ -87,20 +88,15 @@ class PlayersManager: def __delitem__(self, playerName): self._log.debug(f"Removing {playerName} from active players") del self._player_data[playerName] - - @property - def keys(self): - """ - Iterator of the active players' names - """ - return self._player_data.keys() - @property - def items(self): - """ - Two iterators of the activate players' names and object - """ - return self._player_data.items() + def __len__(self): + return len(self._player_data) + + def __iter__(self): + return self._player_data.__iter__() + + def __repr__(self): + return f"Manager is playing {self.gameID} with {len(self._player_data)} active players" @property def gameID(self): @@ -119,6 +115,24 @@ class PlayersManager: def save(self): with open(self._playersPath, 'w') as f: self._cfg = json.dump(f, self._cfg) + + def keys(self): + """ + Iterator of the active players' names + """ + return self._player_data.keys() + + def values(self): + """ + Iterator of the active players' objects + """ + return self._player_data.keys() + + def items(self): + """ + Two iterators of the activate players' names and object + """ + return self._player_data.items() def addExpansion(self, expansion): """ @@ -146,12 +160,14 @@ class Player: Methods: generateConfig: """ - def __init__(self, name: str, manager: PlayersManager, flags: list[str], expansions: dict, games: dict): + def __init__(self, name: str, manager: PlayersManager, **cfg): self._name = name self._manager = manager - self._flags = flags - self._expansions = expansions - self._gameSave = games[manager._currentGameID] if manager._currentGameID is not None else games + for key, val in cfg.items(): + setattr(self, "_" + key, val) + + def __repr__(self): + return f"Player {self._name} has {len(self._flags)} flag(s), {len(self._expansions)} expansions and {len(self._games)} saved game" @property def name(self): @@ -164,6 +180,7 @@ class Player: @flags.setter def flags(self, newFlags): self._flags = newFlags + # The container was changed and must be transmited to the manager self._manager[self._name] = self.generateConfig() @property @@ -173,22 +190,30 @@ class Player: @expansions.setter def expansions(self, newExpansions): self._expansions = newExpansions + # The container was changed and must be transmited to the manager self._manager[self._name] = self.generateConfig() @property def gameSave(self): - return self._gameSave + """The save for the current game. If no configuration was found None is returned.""" + return self._games.get(self._manager.gameID) @gameSave.setter def gameSave(self, newGameSave): - self._gameSave = newGameSave - self._manager[self._name] = self.generateConfig() + self._games[self._manager.gameID] = newGameSave def generateConfig(self): - # Get the config of all games - games = self._manager[self._name] - if self._game is not None: - games[self.manager._currentGameID] = self._gameSave - # Create the config - config = {"flags": self._flags, "expansions": self._expansions, "games": games} - return config + return {"flags": self._flags, "expansions": self._expansions, "games": self._games} + + +if __name__ == "__main__": + # Test run to make sure nothing is flagrantly flawed + configPath = Path(__file__).parent / "players.json" + manager = PlayersManager(playersPath=configPath, gameID="gameID0") + # Iteration + for name in manager: + print(name) + # Modification of a players data + brosef = manager["Brosef"] + brosef.gameSave = [1] + print(manager["Brosef"].gameSave) \ No newline at end of file diff --git a/NoPELib/players.json b/NoPELib/players.json new file mode 100644 index 0000000..6f6b7ca --- /dev/null +++ b/NoPELib/players.json @@ -0,0 +1,19 @@ +{ + "exampleExpansion": { + "optionA": 1, + "optionB": 2 + }, + + "availableExpansion": + { + "bracelet1": "Brosef", + "robotic_barman": "Tango", + "challenge": "TRS" + }, + + "players": { + "Brosef": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 2}}, + "TRS_MML": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 1}}, + "Tango": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 0}} + } +} \ No newline at end of file