from __future__ import annotations from django.db import models from transcendence.abstract.AbstractRoomMember import AbstractRoomMember from transcendence.abstract.AbstractRoom import AbstractRoom from transcendence.abstract.AbstractRoomManager import AbstractRoomManager from profiles.models import ProfileModel from games.models import GameModel from django.contrib.auth.models import User from django.db.models import CASCADE from channels.generic.websocket import WebsocketConsumer # Create your models here.tu class TournamentModel(models.Model): name = models.CharField(max_length = 100) nb_players = models.IntegerField() rounds = models.IntegerField() started = models.BooleanField(default = False) finished = models.BooleanField(default = False) winner = models.ForeignKey(ProfileModel, on_delete=CASCADE) def _add_player(self, player: ProfileModel) -> None: TournamentPlayerModel(player=player, tournament=self).save() def start(self, players: list[ProfileModel]) -> None: self.started = False for player in players: self._add_player(player) for (player1, player2) in zip(players[0::2], players[1::2]): self.create_game([player1, player2], round=1) self.save() def create_game(self, players: list[ProfileModel], round: int) -> GameModel: if (self.started == False): return None if (len(players) != 2): return None from games.models import GameModel game: GameModel = GameModel().create(players=players) TournamentGameModel(tournament=self, game=game, round=round).save() return game def start(self, players: list[ProfileModel]) -> int: if (len(players) != self.nb_players): return 1 for player in players: TournamentPlayerModel(tournament=self, player=player).save() return 0 def get_games(self) -> list[GameModel]: return [tournament_game.game for tournament_game in TournamentGameModel.objects.filter(tournament=self)] def get_games_by_round(self, round: int) -> list[GameModel]: return [tournament_game.game for tournament_game in TournamentGameModel.objects.filter(tournament=self, round=round)] def get_players_by_round(self, round: int) -> list[ProfileModel]: return [game.get_players() for game in self.get_games_by_round(round)] def get_winners_by_round(self, round: int) -> list[ProfileModel]: return [game.winner for game in self.get_games_by_round(round)] def get_players(self) -> list[TournamentPlayerModel]: return TournamentPlayerModel.objects.filter(tournament=self.pk) def get_state(self) -> str: return ("waiting to start", "in progress", "finish")[self.started + self.finished] def is_player(self, profile: ProfileModel) -> bool: return TournamentPlayerModel.objects.filter(player=profile, tournament=self).exists() class TournamentPlayerModel(models.Model): player = models.ForeignKey(ProfileModel, on_delete=CASCADE) tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE) class TournamentGameModel(models.Model): tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE, null=True, blank=True) round = models.IntegerField() game = models.ForeignKey(GameModel, on_delete=CASCADE) class TournamentSpectator(AbstractRoomMember): pass class TournamentPlayer(TournamentSpectator): pass class TournamentRoom(AbstractRoom): def __init__(self, room_manager: TournamentRoomManager, tournament_id: int): super().__init__(room_manager) self.room_manager: TournamentRoomManager self.id: int = id self.model: TournamentModel = TournamentModel.objects.get(pk=tournament_id) def join(self, profile: ProfileModel, socket: WebsocketConsumer) -> TournamentPlayer | TournamentSpectator: if (self.model.started): if (self.model.is_player(profile)): return TournamentPlayer(profile.pk, socket) else: return TournamentSpectator(profile.pk, socket) else: return TournamentSpectator(profile.pk, socket) class TournamentRoomManager(AbstractRoomManager): pass tournament_manager: TournamentRoomManager = TournamentRoomManager()