tournament: add: les crampte

This commit is contained in:
2024-04-22 17:03:45 +02:00
parent 1d8c2c633a
commit aafc61d40a
6 changed files with 191 additions and 152 deletions

View File

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

View File

@ -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):

View File

@ -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