42_ft_transcendence/tournament/models.py
2024-04-16 19:13:18 +02:00

127 lines
4.3 KiB
Python

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()