# Copyright (C) 2023 by Animath # SPDX-License-Identifier: GPL-3.0-or-later from asgiref.sync import sync_to_async from django.conf import settings from django.db import models from django.utils.text import format_lazy from django.utils.translation import gettext_lazy as _ from participation.models import Participation, Tournament class Draw(models.Model): tournament = models.OneToOneField( Tournament, on_delete=models.CASCADE, verbose_name=_('tournament'), ) current_round = models.ForeignKey( 'Round', on_delete=models.CASCADE, null=True, default=None, related_name='+', verbose_name=_('current round'), ) def get_state(self): if self.current_round.current_pool is None: return 'DICE_SELECT_POULES' elif self.current_round.current_pool.current_team is None: return 'DICE_ORDER_POULE' elif self.current_round.current_pool.current_team.purposed is None: return 'WAITING_DRAW_PROBLEM' elif self.current_round.current_pool.current_team.accepted is None: return 'WAITING_CHOOSE_PROBLEM' else: return 'DRAW_ENDED' @property def information(self): s = "" match self.get_state(): case 'DICE_SELECT_POULES': if self.current_round.number == 1: s += """Nous allons commencer le tirage des problèmes.
Vous pouvez à tout moment poser toute question si quelque chose n'est pas clair ou ne va pas.

Nous allons d'abord tirer les poules et l'ordre de passage pour le premier tour avec toutes les équipes puis pour chaque poule, nous tirerons l'ordre de tirage pour le tour et les problèmes.

""" s += """ Les capitaines, vous pouvez désormais toustes lancer un dé 100, en cliquant sur le gros bouton. Les poules et l'ordre de passage lors du premier tour sera l'ordre croissant des dés, c'est-à-dire que le plus petit lancer sera le premier à passer dans la poule A.""" case 'DICE_ORDER_POULE': s += f"""Nous passons au tirage des problèmes pour la poule {self.current_round.current_pool}, entre les équipes {', '.join(td.participation.team.trigram for td in self.current_round.current_pool.teamdraw_set.all())}. Les capitaines peuvent lancer un dé 100 en cliquant sur le gros bouton pour déterminer l'ordre de tirage. L'équipe réalisant le plus gros score pourra tirer en premier.""" s += """

Pour plus de détails sur le déroulement du tirage au sort, le règlement est accessible sur https://tfjm.org/reglement.""" return s async def ainformation(self): return await sync_to_async(lambda: self.information)() class Meta: verbose_name = _('draw') verbose_name_plural = _('draws') class Round(models.Model): draw = models.ForeignKey( Draw, on_delete=models.CASCADE, verbose_name=_('draw'), ) number = models.PositiveSmallIntegerField( choices=[ (1, _('Round 1')), (2, _('Round 2')), ], verbose_name=_('number'), ) current_pool = models.ForeignKey( 'Pool', on_delete=models.CASCADE, null=True, default=None, related_name='+', verbose_name=_('current pool'), ) def __str__(self): return self.get_number_display() class Meta: verbose_name = _('round') verbose_name_plural = _('rounds') class Pool(models.Model): round = models.ForeignKey( Round, on_delete=models.CASCADE, ) letter = models.PositiveSmallIntegerField( choices=[ (1, 'A'), (2, 'B'), (3, 'C'), ], verbose_name=_('letter'), ) size = models.PositiveSmallIntegerField( verbose_name=_('size'), ) current_team = models.ForeignKey( 'TeamDraw', on_delete=models.CASCADE, null=True, default=None, related_name='+', verbose_name=_('current team'), ) @property def trigrams(self): return set(td.participation.team.trigram for td in self.teamdraw_set.all()) def __str__(self): return f"{self.get_letter_display()}{self.round.number}" class Meta: verbose_name = _('pool') verbose_name_plural = _('pools') class TeamDraw(models.Model): participation = models.ForeignKey( Participation, on_delete=models.CASCADE, verbose_name=_('participation'), ) round = models.ForeignKey( Round, on_delete=models.CASCADE, verbose_name=_('round'), ) pool = models.ForeignKey( Pool, on_delete=models.CASCADE, null=True, default=None, verbose_name=_('pool'), ) passage_index = models.PositiveSmallIntegerField( choices=zip(range(1, 5), range(1, 5)), null=True, default=None, verbose_name=_('passage index'), ) choose_index = models.PositiveSmallIntegerField( choices=zip(range(1, 5), range(1, 5)), null=True, default=None, verbose_name=_('choose index'), ) accepted = models.PositiveSmallIntegerField( choices=[ (i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, settings.PROBLEM_COUNT + 1) ], null=True, default=None, verbose_name=_("accepted problem"), ) last_dice = models.PositiveSmallIntegerField( choices=zip(range(1, 101), range(1, 101)), null=True, default=None, verbose_name=_("last dice"), ) purposed = models.PositiveSmallIntegerField( choices=[ (i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, settings.PROBLEM_COUNT + 1) ], null=True, default=None, verbose_name=_("accepted problem"), ) rejected = models.JSONField( default=list, verbose_name=_('rejected problems'), ) def current(self): return TeamDraw.objects.get(participation=self.participation, round=self.round.draw.current_round) class Meta: verbose_name = _('team draw') verbose_name_plural = _('team draws')