Compare commits

...

7 Commits

2 changed files with 113 additions and 43 deletions

View File

@ -36,6 +36,7 @@ class Expansion:
Attributes:
players (tuple of str):
tags (tuple of flag):
config: The config of the expansion. Can't be modified during execution.
Methods:
step:
@ -46,7 +47,7 @@ class Expansion:
onError:
"""
def __init__(self, ID: str, expansionsManager):
def __init__(self, ID: str, expansionsManager: "ExpansionsManager"):
"""
Initialise the creation of an expansion and raise an error if not
available.
@ -57,32 +58,32 @@ class Expansion:
@property
def config(self):
"""
The config of the expansion.
NOTE Can't be modified during execution.
"""
return copy.deepcopy(self._manager.config[self._ID]["config"])
@property
def players(self):
""" Players that have access to this expansion. """
""" Players that have access to the expansion. """
return self._manager.config[self._ID]["players"]
@players.setter
def players(self, newPlayers):
""" Players that have access to this expansion. """
self._manager.config[self._ID]["players"] = tuple(newPlayers)
self._manager.expansionPlayersChanged(self._ID)
self._manager.expansionPlayersChanged(self._ID, newPlayers)
@players.deleter
def players(self):
self._manager.config[self._ID]["players"] = ()
self._manager.expansionPlayersChanged(self._ID)
self._manager.expansionPlayersChanged(self._ID, ())
@property
def tags(self):
""" Players that have access to this expansion. """
""" Tags of the expansion. """
return self._manager.config[self._ID]["tags"]
@tags.setter
def tags(self, newPlayers):
""" Players that have access to this expansion. """
self._manager.config[self._ID]["tags"] = tuple(newPlayers)
@tags.deleter
@ -91,9 +92,6 @@ class Expansion:
@abc.abstractmethod
def step(self, action):
"""
Call close if an error is thrown
"""
raise NotImplementedError
@abc.abstractmethod
@ -132,10 +130,23 @@ class serialShocker(Expansion):
a float within the range [0.0, 1.0] that defines the intensity
"""
vibrateInstead, duration, intensity = action
if vibrateInstead:
self.shocker.vibrate(duration=duration, intensity=intensity)
else:
self.shocker.shock(duration=duration, intensity=intensity)
callFunc = self.shocker.vibrate if vibrateInstead else self.shocker.shock
# Try to execute the step
try:
callFunc(duration=duration, intensity=intensity)
error = None
done = True
except Exception as e:
error = e
done = False
# Return additionnal info
step_info = {
"expansionID": self._ID,
"showOnScreen": None,
"error": error,
"done": done
}
return step_info
def close(self):
pass
@ -163,10 +174,24 @@ class simplest(Expansion):
"""
vibrateInstead, duration, intensity = action
values = f"duration={duration}, intensity={intensity}"
if vibrateInstead:
print(f"Vibrate with {values}")
else:
print(f"Shock with {values}")
interact_type = "Vibrate" if vibrateInstead else "Shock"
# Try to execute the step
try:
message = f"{interact_type} with {values}"
error = None
done = True
except Exception as e:
message = None
error = e
done = False
# Return additionnal info
step_info = {
"expansionID": self._ID,
"showOnScreen": message,
"error": error,
"done": done
}
return step_info
def close(self):
print("Closing")

View File

@ -227,20 +227,6 @@ class Player:
"games": self._gamesSave
}
def punish(self, value, preferedExpansion: str=None):
do_something = lambda value, preferedExpansion: value
additionalInfos = {
"expansionID": "challengeDB",
"balancedValue": 0.2,
"showOnScreen": "Do 100 push-up",
"error": None,
"done": False
}
# NOTE Make a result class instead and an error class
# TODO Implement a way to choose between the available expansions
additionalInfos = do_something(value, preferedExpansion)
return additionalInfos
class ExpansionsManager:
"""
@ -251,6 +237,9 @@ class ExpansionsManager:
Container of the expansions to try making available
activeExpansions: dict of Expansion
Container of the relevent expansions
Methods:
expansionPlayersChanged
"""
defaultExpansionConfig = {"players": (), "types": ()}
keysConvert2Tuple = ("players", "types")
@ -265,6 +254,7 @@ class ExpansionsManager:
"""
# Create the attributes
self.playersManager = playersManager
self._playersLookUp = {}
self._cfg = playersManager.config["expansions"]
if includedExpansions is not None:
self._includedExpansions = tuple(includedExpansions)
@ -320,7 +310,7 @@ class ExpansionsManager:
def _listPossiblyValidExpansions(self):
"""
List expansions that are included, defined in expansionsLib and are available
List expansions that are: included, defined in expansionsLib and available
to at least one active player.
"""
activePlayers = set(self.playersManager.keys())
@ -333,13 +323,20 @@ class ExpansionsManager:
def _createExpansion(self, expansionID):
try:
# Create the expansion
expansion = getattr(expansionsLib, expansionID)(expansionID, self)
except:
pass
else:
self._activeExpansions[expansionID] = expansion
# Update the lookup
for player in self._getPlayersFillMissing(expansionID):
self._playersLookUp[player].append(expansionID)
return expansion
except Exception as e:
return e
def _removeExpansion(self, expansionID):
# Update the lookup
for player in self._getPlayersFillMissing(expansionID):
self._playersLookUp[player].pop(expansionID)
# Remove the expansion
expansion = self._activeExpansions.pop(expansionID)
expansion.close()
del expansion
@ -359,7 +356,11 @@ class ExpansionsManager:
# Add the new expansions
expansionsToAdd = possiblyValidExpansions.difference(previousExpansions)
for expansionID in expansionsToAdd:
self._createExpansion(expansionID)
creation_out = self._createExpansion(expansionID)
if isinstance(creation_out, expansionsLib.Expansion):
self._activeExpansions[expansionID] = creation_out
else:
print(creation_out)
def _activePlayerAdded(self, playerName):
# Find the expansions that are to be created
@ -371,7 +372,11 @@ class ExpansionsManager:
]
# Create the expansions
for expansionID in filteredAddition:
self._createExpansion(expansionID)
creation_out = self._createExpansion(expansionID)
if isinstance(creation_out, expansionsLib.Expansion):
self._activeExpansions[expansionID] = creation_out
else:
print(creation_out)
def _activePlayerRemoved(self, playerName):
# Find the expansions that are to be removed
@ -386,15 +391,55 @@ class ExpansionsManager:
def _errorOccured(self, expansionID):
self._removeExpansion(expansionID)
def expansionPlayersChanged(self, expansionID):
def expansionPlayersChanged(self, expansionID, newPlayers):
"""
Method that allows changing the assigned players of an expansion.
Arguments:
expansionID (str):
newPlayers (tuple of str):
"""
# Save the change
previousPlayers = self._cfg[expansionID]["players"]
self._cfg[expansionID]["players"] = tuple(newPlayers)
# Check the state of the expansion
expansionIsActive = expansionID in self._activeExpansions
activePlayers = set(self.playersManager.keys())
expansionHasNoPlayers = self._getPlayersFillMissing(expansionID).isdisjoint(activePlayers)
expansionDefined = hasattr(expansionsLib, expansionID)
# Update the activation status
activeChanged = False
if expansionIsActive and expansionHasNoPlayers:
self._removeExpansion(expansionID)
activeChanged = True
elif (not expansionIsActive) and (not expansionHasNoPlayers) and expansionDefined:
self._createExpansion(expansionID)
creation_out = self._createExpansion(expansionID)
if isinstance(creation_out, expansionsLib.Expansion):
self._activeExpansions[expansionID] = creation_out
activeChanged = True
elif isinstance(creation_out, Exception):
print(creation_out)
# Update the inverse lookup
if not activeChanged:
removedPlayers = set(previousPlayers).difference(newPlayers)
addedPlayers = set(newPlayers).difference(previousPlayers)
for playerName in removedPlayers:
self._playersLookUp[playerName].pop(expansionID)
for playerName in addedPlayers:
self._playersLookUp[playerName].append(expansionID)
def lookupPlayer(self, playerName):
"""
Get a tuple of all expansions available to a player.
Arguments:
playerName (str): Name of the player
Returns:
expansionsID (tuple of str): ID of the expansions available to the
player
"""
return tuple(self._playersLookUp[playerName])
if __name__ == "__main__":