From 85934f9b3cc59f4c0301d05f984814f0ad4166db Mon Sep 17 00:00:00 2001 From: even-gits Date: Thu, 27 Feb 2025 15:15:23 +0100 Subject: [PATCH] *Update: Players now have UUIDs --- src/core.py | 102 ++++++++++++++++++---------------------------------- 1 file changed, 35 insertions(+), 67 deletions(-) diff --git a/src/core.py b/src/core.py index bb21bdf..eb345a4 100644 --- a/src/core.py +++ b/src/core.py @@ -18,10 +18,10 @@ from tqdm import tqdm # pyright: ignore import json # pyright: ignore from .pairing_logic.examples import PairingRandom, PairingSnake, PairingDefault -import uuid +from uuid import UUID, uuid4 import sys -sys.setrecursionlimit(5000) # Increase recursion limit +#sys.setrecursionlimit(5000) # Increase recursion limit class PodsExport: @classmethod @@ -107,10 +107,10 @@ class Format(Enum): }), Field.ID: Json2Obj({ 'name': 'ID', - 'format': '{:d}', + 'format': '{:s}', 'denom': None, 'description': 'Player ID', - 'getter': lambda p: p.ID + 'getter': lambda p: p.ID.hex }), Field.NAME: Json2Obj({ 'name': 'name', @@ -299,10 +299,10 @@ class ID: def __init__(self): self._last_ID = 0 - def next(self) -> int: + def next(self) -> UUID: #self._last_ID += 1 #return self._last_ID - return uuid.uuid4() + return uuid4() class TournamentAction: @@ -332,9 +332,10 @@ def action(cls, func) -> Callable: @StandingsExport.auto_export @PodsExport.auto_export def wrapper(self, *original_args, **original_kwargs): - before = deepcopy(self, memo={}) + memo = {} + before = deepcopy(self, memo=memo) ret = func(self, *original_args, **original_kwargs) - after = deepcopy(self, memo={}) #TODO: Crash + after = deepcopy(self, memo=memo) cls.ACTIONS.append(TournamentAction( before, ret, after, func.__name__, *original_args, **original_kwargs, )) @@ -868,6 +869,7 @@ def construct(self): class Player(IPlayer): + CACHE: dict[UUID, IPlayer] = {} SORT_METHOD: SORT_METHOD = SORT_METHOD.ID SORT_ORDER: SORT_ORDER = SORT_ORDER.ASCENDING FORMATTING = ['-p'] @@ -878,8 +880,16 @@ def __init__(self, name:str, tour: Tournament|ITournament): self.name = name self.points = 0 self.ID = tour.TC.player_id.next() + self.CACHE[self.ID] = self self.opponents_beaten = set() + @classmethod + def get(cls, ID: UUID, tour: Tournament|ITournament): + if ID not in cls.CACHE: + cls.CACHE[ID] = cls('', tour) + cls.CACHE[ID].ID = ID + return cls.CACHE[ID] + @property def players_beaten(self) -> list[Player]: players = set() @@ -1164,18 +1174,23 @@ def __repr__(self, tokens=None): return ' | '.join(fields) - class Pod(IPod): def __init__(self, round: Round, id, cap=0): super().__init__() self.id = id self.cap = cap self.players: list[Player] = list() + #self._players: list[UUID] = list() #TODO: make references to players self.round: Round = round self.result: Sequence[IPlayer|Player] = None self.won: None|Player = None self.draw: list[Player] = list() + #@property + #def players(self) -> list[Player]: + # x = [Player.get(ID, self.round.tour) for ID in self._players] + # return x + @override def add_player(self, player: Player, manual=False) -> bool: if len(self) >= self.cap and self.cap and not manual: @@ -1187,6 +1202,17 @@ def add_player(self, player: Player, manual=False) -> bool: return True + def remove_player(self, player: Player, cleanup=True) -> Player|None: + try: + idx = self.players.index(player) + except ValueError: + return None + p = self.players.pop(idx) + player.location = IPlayer.ELocation.UNSEATED + if len(self) == 0 and cleanup: + self.round.remove_pod(self) + return player + @property def average_seat(self) -> float: return np.average([p.average_seat for p in self.players]).astype(float) @@ -1241,17 +1267,6 @@ def clear(self): p.location = IPlayer.ELocation.UNSEATED self.players.clear() - def remove_player(self, player: Player, cleanup=True) -> Player|None: - try: - idx = self.players.index(player) - except ValueError: - return None - p = self.players.pop(idx) - p.location = IPlayer.ELocation.UNSEATED - if len(self) == 0 and cleanup: - self.round.remove_pod(self) - return p - @property def name(self): return 'Pod {}'.format(self.id) @@ -1413,50 +1428,3 @@ def conclude(self): p.result = IPlayer.EResult.PENDING pass - def conclude(self): - for pod in self.pods: - for p in pod.players: - p.pods.append(pod) - - for p in self.unseated: - if p.result == Player.EResult.LOSS: - p.pods.append(Player.EResult.LOSS) - elif self.tour.TC.allow_bye: - p.points += self.tour.TC.bye_points - p.result = Player.EResult.BYE - p.pods.append(Player.EResult.BYE) - - self.tour.rounds.append(self) - self.concluded = datetime.now() - self.players = deepcopy(self.players) - Log.log('{}{}{}'.format( - 30*'*', '\nRound completed!\n', 30*'*',), Log.Level.INFO) - self.tour.round = None - for p in self.tour.players: - p.location = IPlayer.ELocation.UNSEATED - p.result = IPlayer.EResult.PENDING - pass - - def conclude(self): - for pod in self.pods: - for p in pod.players: - p.pods.append(pod) - - for p in self.unseated: - if p.result == Player.EResult.LOSS: - p.pods.append(Player.EResult.LOSS) - elif self.tour.TC.allow_bye: - p.points += self.tour.TC.bye_points - p.result = Player.EResult.BYE - p.pods.append(Player.EResult.BYE) - - self.tour.rounds.append(self) - self.concluded = datetime.now() - self.players = deepcopy(self.players) - Log.log('{}{}{}'.format( - 30*'*', '\nRound completed!\n', 30*'*',), Log.Level.INFO) - self.tour.round = None - for p in self.tour.players: - p.location = IPlayer.ELocation.UNSEATED - p.result = IPlayer.EResult.PENDING - pass \ No newline at end of file