Use more complex calculus to mix teams for the second day

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-03-31 17:15:34 +02:00
parent cf8892ee1a
commit 14505260ff
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
3 changed files with 51 additions and 40 deletions

View File

@ -93,7 +93,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
@ensure_orga @ensure_orga
async def start_draw(self, fmt, **kwargs): async def start_draw(self, fmt, **kwargs):
try: try:
fmt = list(map(int, fmt.split('+'))) fmt = sorted(map(int, fmt.split('+')), reverse=True)
except ValueError as e: except ValueError as e:
return await self.alert(_("Invalid format"), 'danger') return await self.alert(_("Invalid format"), 'danger')
@ -102,6 +102,9 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
_("The sum must be equal to the number of teams: expected {len}, got {sum}")\ _("The sum must be equal to the number of teams: expected {len}, got {sum}")\
.format(len=len(self.participations), sum=sum(fmt)), 'danger') .format(len=len(self.participations), sum=sum(fmt)), 'danger')
if fmt.count(5) > 1:
return await self.alert(_("There can be at most one pool with 5 teams."), 'danger')
draw = await Draw.objects.acreate(tournament=self.tournament) draw = await Draw.objects.acreate(tournament=self.tournament)
r1 = None r1 = None
for i in [1, 2]: for i in [1, 2]:
@ -236,31 +239,31 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
tds_copy = tds.copy() tds_copy = tds.copy()
async for p in Pool.objects.filter(round_id=self.tournament.draw.current_round_id).order_by('letter').all(): async for p in Pool.objects.filter(round_id=self.tournament.draw.current_round_id).order_by('letter').all():
while (c := await TeamDraw.objects.filter(pool=p).acount()) < p.size: pool_tds = sorted(tds_copy[:p.size], key=lambda td: (td.passage_dice * 27) % 100)
td = tds_copy.pop(0) tds_copy = tds_copy[p.size:]
for i, td in enumerate(pool_tds):
td.pool = p td.pool = p
td.passage_index = c td.passage_index = i
await sync_to_async(td.save)() await sync_to_async(td.save)()
if self.tournament.draw.current_round.number == 2 \ tds_copy = tds.copy()
and await self.tournament.draw.current_round.pool_set.acount() >= 2: round2 = await self.tournament.draw.round_set.filter(number=2).aget()
# Check that we don't have a same pool as the first day round2_pools = await sync_to_async(lambda: list(Pool.objects.filter(
async for p1 in Pool.objects.filter(round__draw=self.tournament.draw, round__number=1).all(): round__draw__tournament=self.tournament, round=round2).order_by('letter').all()))()
async for p2 in Pool.objects.filter(round_id=self.tournament.draw.current_round_id).all(): current_pool_id, current_passage_index = 0, 0
if await sync_to_async(lambda: set(td['id'] for td in p1.teamdraw_set.values('id')))() \ for i, td in enumerate(tds_copy):
== await sync_to_async(lambda:set(td['id'] for td in p2.teamdraw_set.values('id')))(): if i == len(tds) - 1 and round2_pools[0].size == 5:
await TeamDraw.objects.filter(round=self.tournament.draw.current_round)\ current_pool_id = 0
.aupdate(passage_dice=None, pool=None, passage_index=None) current_passage_index = 4
for td in tds:
await self.channel_layer.group_send( td2 = await TeamDraw.objects.filter(participation=td.participation, round=round2).aget()
f"tournament-{self.tournament.id}", td2.pool = round2_pools[current_pool_id]
{'type': 'draw.dice', 'team': td.participation.team.trigram, 'result': None}) td2.passage_index = current_passage_index
await self.channel_layer.group_send( current_pool_id += 1
f"tournament-{self.tournament.id}", if current_pool_id == len(round2_pools):
{'type': 'draw.alert', current_pool_id = 0
'message': _('Two pools are identical. Please relaunch your dices.'), current_passage_index += 1
'alert_type': 'warning'}) await sync_to_async(td2.save)()
return
pool = await Pool.objects.filter(round=self.tournament.draw.current_round, letter=1).aget() pool = await Pool.objects.filter(round=self.tournament.draw.current_round, letter=1).aget()
self.tournament.draw.current_round.current_pool = pool self.tournament.draw.current_round.current_pool = pool
@ -269,8 +272,10 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
msg = "Les résultats des dés sont les suivants : " msg = "Les résultats des dés sont les suivants : "
msg += await sync_to_async(lambda: ", ".join( msg += await sync_to_async(lambda: ", ".join(
f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})" f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})"
for td in self.tournament.draw.current_round.team_draws))() for td in tds))()
msg += ". L'ordre de passage et les compositions des différentes poules sont affiché⋅es sur le côté." msg += ". L'ordre de passage et les compositions des différentes poules sont affiché⋅es sur le côté. "
msg += "Attention : les ordres de passage sont déterminés à partir des scores des dés, mais ne sont pas "
msg += "directement l'ordre croissant des dés, afin d'avoir des poules mélangées."
self.tournament.draw.last_message = msg self.tournament.draw.last_message = msg
await sync_to_async(self.tournament.draw.save)() await sync_to_async(self.tournament.draw.save)()
@ -291,6 +296,9 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules', {'type': 'draw.send_poules',
'round': self.tournament.draw.current_round}) 'round': self.tournament.draw.current_round})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
'round': await self.tournament.draw.round_set.filter(number=2).aget()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info', 'draw': self.tournament.draw}) {'type': 'draw.set_info', 'draw': self.tournament.draw})

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-28 21:55+0200\n" "POT-Creation-Date: 2023-03-31 17:14+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -39,44 +39,44 @@ msgid "The sum must be equal to the number of teams: expected {len}, got {sum}"
msgstr "" msgstr ""
"La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}" "La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}"
#: draw/consumers.py:128 #: draw/consumers.py:106
msgid "There can be at most one pool with 5 teams."
msgstr "Il ne peut y avoir au plus qu'une seule poule de 5 équipes."
#: draw/consumers.py:131
msgid "Draw started!" msgid "Draw started!"
msgstr "Le tirage a commencé !" msgstr "Le tirage a commencé !"
#: draw/consumers.py:138 #: draw/consumers.py:141
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} will start." msgid "The draw for the tournament {tournament} will start."
msgstr "Le tirage au sort du tournoi {tournament} va commencer." msgstr "Le tirage au sort du tournoi {tournament} va commencer."
#: draw/consumers.py:149 #: draw/consumers.py:152
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} is aborted." msgid "The draw for the tournament {tournament} is aborted."
msgstr "Le tirage au sort du tournoi {tournament} est annulé." msgstr "Le tirage au sort du tournoi {tournament} est annulé."
#: draw/consumers.py:183 draw/consumers.py:186 #: draw/consumers.py:186 draw/consumers.py:189
msgid "You've already launched the dice." msgid "You've already launched the dice."
msgstr "Vous avez déjà lancé le dé." msgstr "Vous avez déjà lancé le dé."
#: draw/consumers.py:189 #: draw/consumers.py:192
msgid "It is not your turn." msgid "It is not your turn."
msgstr "Ce n'est pas votre tour." msgstr "Ce n'est pas votre tour."
#: draw/consumers.py:191 draw/consumers.py:362 draw/consumers.py:406 #: draw/consumers.py:194 draw/consumers.py:370 draw/consumers.py:414
#: draw/consumers.py:535 #: draw/consumers.py:543
msgid "This is not the time for this." msgid "This is not the time for this."
msgstr "Ce n'est pas le moment pour cela." msgstr "Ce n'est pas le moment pour cela."
#: draw/consumers.py:227 draw/consumers.py:325 #: draw/consumers.py:230 draw/consumers.py:333
#, python-brace-format #, python-brace-format
msgid "Dices from teams {teams} are identical. Please relaunch your dices." msgid "Dices from teams {teams} are identical. Please relaunch your dices."
msgstr "" msgstr ""
"Les dés des équipes {teams} sont identiques. Merci de relancer vos dés." "Les dés des équipes {teams} sont identiques. Merci de relancer vos dés."
#: draw/consumers.py:261 #: draw/consumers.py:615
msgid "Two pools are identical. Please relaunch your dices."
msgstr "Deux poules sont identiques. Merci de relancer vos dés."
#: draw/consumers.py:607
msgid "This is only available for the final tournament." msgid "This is only available for the final tournament."
msgstr "Cela n'est possible que pour la finale." msgstr "Cela n'est possible que pour la finale."
@ -2232,6 +2232,9 @@ msgstr "Résultats"
msgid "No results found." msgid "No results found."
msgstr "Aucun résultat." msgstr "Aucun résultat."
#~ msgid "Two pools are identical. Please relaunch your dices."
#~ msgstr "Deux poules sont identiques. Merci de relancer vos dés."
#~ msgid "last dice" #~ msgid "last dice"
#~ msgstr "dernier dé" #~ msgstr "dernier dé"

View File

@ -282,7 +282,7 @@ class Tournament(models.Model):
def best_format(self): def best_format(self):
n = len(self.participations.filter(valid=True).all()) n = len(self.participations.filter(valid=True).all())
fmt = [n] if n <= 5 else [3] * (n // 3 - 1) + [3 + n % 3] fmt = [n] if n <= 5 else [3] * (n // 3 - 1) + [3 + n % 3]
return '+'.join(map(str, fmt)) return '+'.join(map(str, sorted(fmt, reverse=True)))
def get_absolute_url(self): def get_absolute_url(self):