from django.db import models from channels.generic.websocket import WebsocketConsumer from games.models import GameModel import json from transcendence.abstract.AbstractRoomMember import AbstractRoomMember from transcendence.abstract.AbstractRoom import AbstractRoom from transcendence.abstract.AbstractRoomManager import AbstractRoomManager # Create your models here.tu class TournamentModel(models.Model): name = models.CharField(max_length=100) nb_players = models.IntegerField() nb_players_by_game = models.IntegerField() level = models.IntegerField() started = models.BooleanField(default=False) finished = models.BooleanField(default=False) def create_game(self, level, users_id): game_id = GameModel().create(users_id=users_id) TournamentGamesModel(game_id=game_id, tournament_id=self.pk, tournament_level=level).save() return game_id def get_games_id_by_level(self, level): tmp = TournamentGamesModel.objects.filter(tournament_id=self.pk, tournament_level=level) return [instance.game_id for instance in tmp] def get_games_id(self): return list(TournamentGamesModel.objects.filter(tournament_id=self.pk)) def get_players_id(self): return [model.participant_id for model in TournamentParticipantsModel.objects.filter(tournament_id=self.pk)] def is_a_participant(self, participant_id: int): return TournamentParticipantsModel.objects.filter(participant_id=participant_id, tournament_id=self.pk).exists() def add_participants(self, participants_id: [int]): for participant_id in participants_id: TournamentParticipantsModel(tournament_id=self.pk, participant_id=participant_id).save() def start(self, participants_id: [int]): self.started = True self.add_participants(participants_id) games_id = [int] for i in range(0, len(participants_id), self.nb_players_by_game): game_id = self.create_game(0, participants_id[i : i + self.nb_players_by_game]) games_id.append(game_id) self.save() return games_id class TournamentParticipantsModel(models.Model): tournament_id = models.IntegerField() participant_id = models.IntegerField() class TournamentGamesModel(models.Model): tournament_id = models.IntegerField() tournament_level = models.IntegerField() game_id = models.IntegerField() class TournamentMember(AbstractRoomMember): def __init__(self, user_id: int, socket: WebsocketConsumer, room): super().__init__(user_id, socket) self.participate = False self.room = room def receive(self, text_data: str = None, byte_dates: bytes = None): if (text_data is None): return data: dict = json.loads(text_data) if (data.get("participate") is not None): self.room.update_participants(self) def send_error_message(self, message: str): self.send("error", {"error_message": message}) def go_to(self, url: str): self.send("go_to", {"url": url}) def send_participating(self): self.send("is_participant", {"is_participant": self.participate}) class TournamentRoom(AbstractRoom): def __init__(self, room_manager, tournament_id: int): super().__init__(room_manager) self.tournament_id = tournament_id self.tournament = TournamentModel.objects.get(pk=tournament_id) def start(self): self.broadcast("tournament_start") games_id = self.tournament.start(self.get_participants_id()) for i, participant in enumerate(self.get_participants()): participant: TournamentMember participant.go_to(f"games/{games_id[i // self.tournament.nb_players_by_game]}") def update_participants(self, member: TournamentMember): if (self.tournament.started): member.send_error_message("Tournament already started") return member.participate = not member.participate nb_participants = self.get_nb_participants() self.broadcast("update_participants", {"nb_participants": nb_participants}) member.send_participating() if (nb_participants == self.tournament.nb_players): self.start() def get_nb_participants(self): if (self.tournament.started): return self.tournament.nb_players nb_participants = 0 for member in self._member_list: member: TournamentMember if (member.participate): nb_participants += 1 return nb_participants def get_participants(self): return [member for member in self._member_list if member.participate] def get_participants_id(self): return [member.user_id for member in self._member_list if member.participate] def append(self, member: TournamentMember): super().append(member) if self.tournament.started: member.participate = self.tournament.is_a_participant(member.user_id) member.send_participating() member.send("nb_participants", {"nb_participants": self.get_nb_participants()}) class TournamentRoomManager(AbstractRoomManager): def get(self, tournament_id: int): for room in self._room_list: if (room.tournament_id == tournament_id): return room if (TournamentModel.objects.filter(pk = tournament_id, finished=False).exists()): room = TournamentRoom(self, tournament_id) self.append(room) return room return None tournament_manager: TournamentRoomManager = TournamentRoomManager()