ft_transcendence/tournament/models.py

154 lines
5.0 KiB
Python
Raw Permalink Normal View History

2023-12-20 13:15:47 -05:00
from django.db import models
from channels.generic.websocket import WebsocketConsumer
2023-12-20 13:15:47 -05:00
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
2023-12-20 13:15:47 -05:00
# Create your models here.tu
class TournamentModel(models.Model):
2023-12-26 15:35:08 -05:00
name = models.CharField(max_length = 100)
2023-12-20 13:15:47 -05:00
nb_players = models.IntegerField()
nb_players_by_game = models.IntegerField()
level = models.IntegerField()
2023-12-26 15:35:08 -05:00
started = models.BooleanField(default = False)
finished = models.BooleanField(default = False)
2023-12-20 13:15:47 -05:00
2023-12-26 15:32:20 -05:00
def create_game(self, level, players_id):
game_id = GameModel().create(players_id = players_id)
TournamentGamesModel(game_id = game_id, tournament_id = self.pk, tournament_level = level).save()
2023-12-20 13:15:47 -05:00
return game_id
def get_games_id_by_level(self, level):
2023-12-26 15:32:20 -05:00
tmp = TournamentGamesModel.objects.filter(tournament_id = self.pk, tournament_level = level)
2023-12-26 12:24:23 -05:00
return [instance.game_id for instance in tmp]
2023-12-20 13:15:47 -05:00
def get_games_id(self):
2023-12-26 15:32:20 -05:00
return [tournament_game.game_id for tournament_game in TournamentGamesModel.objects.filter(tournament_id = self.pk)]
2023-12-20 13:15:47 -05:00
def get_players_id(self):
2023-12-26 12:24:23 -05:00
return [model.participant_id for model in TournamentParticipantsModel.objects.filter(tournament_id=self.pk)]
def is_a_participant(self, participant_id: int):
2023-12-26 15:35:08 -05:00
return TournamentParticipantsModel.objects.filter(participant_id = participant_id, tournament_id = self.pk).exists()
2023-12-26 12:24:23 -05:00
def add_participants(self, participants_id: [int]):
for participant_id in participants_id:
2023-12-26 15:35:08 -05:00
TournamentParticipantsModel(tournament_id = self.pk, participant_id = participant_id).save()
2023-12-26 12:24:23 -05:00
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()
2023-12-20 13:15:47 -05:00
class TournamentGamesModel(models.Model):
tournament_id = models.IntegerField()
tournament_level = models.IntegerField()
game_id = models.IntegerField()
class TournamentMember(AbstractRoomMember):
2023-12-26 12:24:23 -05:00
def __init__(self, user_id: int, socket: WebsocketConsumer, room):
super().__init__(user_id, socket)
self.participate = False
2023-12-26 12:24:23 -05:00
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)
2023-12-26 12:24:23 -05:00
if (data.get("participate") is not None):
self.room.update_participants(self)
2023-12-26 12:24:23 -05:00
def send_error_message(self, message: str):
self.send("error", {"error_message": message})
2023-12-26 12:24:23 -05:00
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
2023-12-26 15:35:08 -05:00
self.tournament = TournamentModel.objects.get(pk = tournament_id)
def start(self):
self.broadcast("tournament_start")
2023-12-26 12:24:23 -05:00
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})
2023-12-26 12:24:23 -05:00
member.send_participating()
if (nb_participants == self.tournament.nb_players):
self.start()
def get_nb_participants(self):
2023-12-26 12:24:23 -05:00
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):
2023-12-26 12:24:23 -05:00
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)
2023-12-26 12:24:23 -05:00
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
2023-12-26 15:35:08 -05:00
if (TournamentModel.objects.filter(pk = tournament_id).exists()):
room = TournamentRoom(self, tournament_id)
self.append(room)
return room
return None
tournament_manager: TournamentRoomManager = TournamentRoomManager()