127 lines
4.3 KiB
Python
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() |