tournament: add: les crampte
This commit is contained in:
@ -6,7 +6,7 @@ from django.contrib.auth.models import User
|
||||
from django.db.models import QuerySet
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
from games.models import GameModel
|
||||
from profiles.models import ProfileModel
|
||||
from profiles.serializers.ProfileSerializer import ProfileSerializer
|
||||
from .models import TournamentModel
|
||||
@ -31,6 +31,9 @@ class TournamentMember:
|
||||
data_to_send.update(data)
|
||||
|
||||
self.send("error", data_to_send)
|
||||
|
||||
def send_goto(self, game: GameModel):
|
||||
self.send("go_to", {"game_id": game.pk})
|
||||
|
||||
def _receive_participating(self, data: dict) -> None:
|
||||
|
||||
@ -38,20 +41,18 @@ class TournamentMember:
|
||||
if (is_participating is None):
|
||||
self.send_error(_("Missing is_participating statement."))
|
||||
return
|
||||
self._room.set_participation()
|
||||
|
||||
self._room.set_participation(self, is_participating)
|
||||
|
||||
def receive(self, data: dict):
|
||||
|
||||
if self.is_participating == False:
|
||||
return
|
||||
|
||||
detail: str | None = data.get("detail")
|
||||
if (detail is None):
|
||||
return
|
||||
|
||||
match(detail):
|
||||
case "update_particapating":
|
||||
self._receive_participating()
|
||||
case "update_participating":
|
||||
self._receive_participating(data)
|
||||
case _:
|
||||
print("bozo_send")
|
||||
|
||||
@ -80,16 +81,35 @@ class TournamentRoom:
|
||||
|
||||
def __init__(self, room_manager: TournamentRoomManager, tournament: TournamentModel):
|
||||
self._room_manager: TournamentRoomManager = room_manager
|
||||
self._member_list: list[TournamentMember] = []
|
||||
self._member_list: set[TournamentMember] = set()
|
||||
self._model: TournamentModel = tournament
|
||||
|
||||
def join(self, socket: TournamentWebConsumer) -> TournamentMember:
|
||||
|
||||
member: TournamentMember = TournamentMember(socket, self)
|
||||
self._member_list.append(member)
|
||||
self._member_list.add(member)
|
||||
|
||||
return member
|
||||
|
||||
def get_participants_profiles(self) -> list[ProfileModel]:
|
||||
return [participant._socket.user.profilemodel for participant in self.get_participants()]
|
||||
|
||||
def start(self) -> None:
|
||||
|
||||
games: list[GameModel] = self._model.start()
|
||||
|
||||
self.broadcast("start")
|
||||
|
||||
for game in games:
|
||||
for player in game.get_players():
|
||||
participant: TournamentMember = self.get_participant_by_profile(player)
|
||||
participant.send_goto(game)
|
||||
|
||||
def get_participant_by_profile(self, profile: ProfileModel):
|
||||
for participant in self.get_participants():
|
||||
if (participant._socket.user.profilemodel == profile):
|
||||
return participant
|
||||
|
||||
def leave(self, member: TournamentMember) -> None:
|
||||
|
||||
# Delete room if nobody connected, no cringe memory leak
|
||||
@ -100,10 +120,13 @@ class TournamentRoom:
|
||||
self._member_list.remove(member)
|
||||
|
||||
self.set_participation(member, False)
|
||||
|
||||
def everybody_is_here(self):
|
||||
return len(self.get_participants()) == self._model.nb_participants
|
||||
|
||||
def broadcast(self, detail: str, data: dict, excludes: list[TournamentMember] = []) -> None:
|
||||
def broadcast(self, detail: str, data: dict, excludes: set[TournamentMember] = set()) -> None:
|
||||
|
||||
member_list: list[TournamentMember] = [member for member in self._member_list if member not in excludes]
|
||||
member_list: list[TournamentMember] = self._member_list - excludes
|
||||
|
||||
for member in member_list:
|
||||
member.send(detail, data)
|
||||
@ -120,11 +143,14 @@ class TournamentRoom:
|
||||
return
|
||||
|
||||
if (is_participating == True):
|
||||
self.broadcast("add_participant", {"profile", ProfileSerializer(member._socket.user.profilemodel).data})
|
||||
self.broadcast("add_participant", {"participant": ProfileSerializer(member._socket.user.profilemodel).data})
|
||||
else:
|
||||
self.broadcast("del_participant", {"profile", ProfileSerializer(member._socket.user.profilemodel).data})
|
||||
self.broadcast("del_participant", {"participant": ProfileSerializer(member._socket.user.profilemodel).data})
|
||||
|
||||
member.is_participating = is_participating
|
||||
|
||||
if self.everybody_is_here():
|
||||
self.start()
|
||||
|
||||
tournament_manager: TournamentRoomManager = TournamentRoomManager()
|
||||
|
||||
|
@ -1,21 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
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
|
||||
from django.db import models
|
||||
|
||||
import json
|
||||
|
||||
|
||||
# Create your models here.tu
|
||||
class TournamentModel(models.Model):
|
||||
|
||||
name = models.CharField(max_length = 100)
|
||||
@ -23,12 +14,14 @@ class TournamentModel(models.Model):
|
||||
round = models.IntegerField()
|
||||
started = models.BooleanField(default = False)
|
||||
finished = models.BooleanField(default = False)
|
||||
winner = models.ForeignKey(ProfileModel, on_delete=CASCADE, blank=True, null=True)
|
||||
winner = models.ForeignKey(User, on_delete=CASCADE, blank=True, null=True)
|
||||
|
||||
def _register_participant(self, participant: ProfileModel) -> None:
|
||||
def _register_participant(self, participant: User) -> None:
|
||||
TournamentParticipantModel(participant=participant, tournament=self).save()
|
||||
|
||||
def start(self, participants: list[ProfileModel]) -> None:
|
||||
def start(self, participants: list[User]) -> None:
|
||||
|
||||
games: list[GameModel] = []
|
||||
|
||||
self.started = True
|
||||
|
||||
@ -36,11 +29,14 @@ class TournamentModel(models.Model):
|
||||
self._register_participant(player)
|
||||
|
||||
for (participant1, participant2) in zip(participants[0::2], participants[1::2]):
|
||||
self.create_game([participant1, participant2], round=1)
|
||||
game: GameModel = self.create_game([participant1, participant2], round=1)
|
||||
games.append(game)
|
||||
|
||||
self.save()
|
||||
|
||||
def create_game(self, participants: list[ProfileModel], round: int) -> GameModel:
|
||||
return games
|
||||
|
||||
def create_game(self, participants: list[User], round: int) -> GameModel:
|
||||
|
||||
if (self.started == False):
|
||||
return None
|
||||
@ -62,10 +58,10 @@ class TournamentModel(models.Model):
|
||||
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]:
|
||||
def get_players_by_round(self, round: int) -> list[User]:
|
||||
return [game.get_players() for game in self.get_games_by_round(round)]
|
||||
|
||||
def get_winners_by_round(self, round: int) -> list[ProfileModel]:
|
||||
def get_winners_by_round(self, round: int) -> list[User]:
|
||||
return [game.winner for game in self.get_games_by_round(round)]
|
||||
|
||||
def get_participants(self) -> list[TournamentParticipantModel]:
|
||||
@ -74,13 +70,12 @@ class TournamentModel(models.Model):
|
||||
def get_state(self) -> str:
|
||||
return ("waiting to start", "in progress", "finish")[self.started + self.finished]
|
||||
|
||||
def is_participanting(self, profile: ProfileModel) -> bool:
|
||||
def is_participanting(self, profile: User) -> bool:
|
||||
return TournamentParticipantModel.objects.filter(participant=profile, tournament=self).exists()
|
||||
|
||||
class TournamentParticipantModel(models.Model):
|
||||
participant = models.ForeignKey(ProfileModel, on_delete=CASCADE)
|
||||
participant = models.ForeignKey(User, on_delete=CASCADE)
|
||||
tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE)
|
||||
#prout à encore frappé
|
||||
|
||||
class TournamentGameModel(models.Model):
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from django.db.models.query import QuerySet
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .models import TournamentModel
|
||||
|
||||
from profiles.models import ProfileModel
|
||||
from profiles.serializers.ProfileSerializer import ProfileSerializer
|
||||
from games.serializers import GameSerializer
|
||||
|
||||
nb_participants = [2 ** i for i in range(2, 6)]
|
||||
|
||||
class TournamentSerializer(serializers.ModelSerializer):
|
||||
|
||||
state = serializers.SerializerMethodField(read_only=True, required=False)
|
||||
@ -30,16 +28,6 @@ class TournamentSerializer(serializers.ModelSerializer):
|
||||
return ["waiting", "started", "finished"][instance.started + instance.finished]
|
||||
|
||||
def validate_nb_participants(self, value: int):
|
||||
if (value < 2):
|
||||
raise serializers.ValidationError("The numbers of participants must be greather than 2.")
|
||||
return value
|
||||
|
||||
def validate_nb_participants_by_game(self, value: int):
|
||||
if (value < 2):
|
||||
raise serializers.ValidationError("The numbers of participants by game must be greather than 2.")
|
||||
nb_participants: str = self.initial_data.get("nb_participants")
|
||||
if (nb_participants is not None and nb_participants.isnumeric()):
|
||||
nb_participants: int = int(nb_participants)
|
||||
if (value > nb_participants):
|
||||
raise serializers.ValidationError("The numbers of participants by game must be smaller than the numbers of participants.")
|
||||
if (value not in nb_participants):
|
||||
raise serializers.ValidationError(f"The numbers of participants must be {str(nb_participants)}.")
|
||||
return value
|
Reference in New Issue
Block a user