from __future__ import annotations from games.models import GameModel from django.contrib.auth.models import User from django.db.models import CASCADE from django.db import models class TournamentModel(models.Model): name = models.CharField(max_length = 100) nb_participants = models.IntegerField() round = models.IntegerField() started = models.BooleanField(default = False) finished = models.BooleanField(default = False) winner = models.ForeignKey(User, on_delete=CASCADE, blank=True, null=True) def _register_participant(self, participant: User) -> None: TournamentParticipantModel(participant=participant, tournament=self).save() def create_round(self, participants: set[User], round: int) -> set[GameModel]: game_list: set[GameModel] = set() for i, (participant1, participant2) in enumerate(zip(participants[0::2], participants[1::2])): game: GameModel = self.create_game([participant1, participant2], round, i) game_list.add(game) return game_list def start(self, participant_list: set[User]) -> None: self.started = True self.round = 1 for participant in participant_list: self._register_participant(participant) self.save() def finish(self, winner: User): self.finished = True self.winner = winner self.save() def create_game(self, participants: set[User], round: int, pos: int) -> GameModel: if (self.started == False): return None if (len(participants) != 2): return None from games.models import GameModel game: GameModel = GameModel().create(participants) TournamentGameModel(tournament=self, game=game, round=round, pos=pos).save() return game def get_games(self) -> set[GameModel]: return {games for games in self.get_games_by_round(i for i in range(1, self.round))} def get_games_by_round(self, round: int) -> set[GameModel]: return {tournament_game for tournament_game in TournamentGameModel.objects.filter(tournament=self, round=round)} def get_participants_by_round(self, round: int) -> set[User]: if round == 1: return self.get_participants() return {game.winner for game in self.get_games_by_round(round - 1)} def get_winners_by_round(self, round: int) -> set[User]: return {game.winner for game in self.get_games_by_round(round)} def get_participants(self) -> set[User]: return {tournament_participant.participant for tournament_participant in TournamentParticipantModel.objects.filter(tournament=self.pk)} def get_state(self) -> str: return ("waiting to start", "in progress", "finish")[self.started + self.finished] def is_participating(self, profile: User) -> bool: return TournamentParticipantModel.objects.filter(participant=profile, tournament=self).exists() class TournamentParticipantModel(models.Model): participant = models.ForeignKey(User, on_delete=CASCADE) tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE) class TournamentGameModel(GameModel): tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE, null=True, blank=True) round = models.IntegerField() pos = models.IntegerField() def finish(self, winner_id): super().finish(winner_id) from .consumers import tournament_manager room = tournament_manager.get(self.tournament) room.set_game_as_finished(self)