From 92abcb584c07b537a4b379d03b7c5adc819d8fd6 Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart" Date: Sun, 15 Jun 2025 15:09:48 +0200 Subject: [PATCH] Add value field to MusicGameOrder and update score calculation logic --- game/migrations/0022_musicgameorder_value.py | 17 ++++++++++++ game/models.py | 25 +++++++++++++++++ game/views.py | 28 +++----------------- 3 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 game/migrations/0022_musicgameorder_value.py diff --git a/game/migrations/0022_musicgameorder_value.py b/game/migrations/0022_musicgameorder_value.py new file mode 100644 index 0000000..712353c --- /dev/null +++ b/game/migrations/0022_musicgameorder_value.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-06-15 12:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("game", "0021_alter_musicgameresults_score"), + ] + + operations = [ + migrations.AddField( + model_name="musicgameorder", + name="value", + field=models.PositiveIntegerField(default=0), + ), + ] diff --git a/game/models.py b/game/models.py index bf57c6e..fa84cbd 100644 --- a/game/models.py +++ b/game/models.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import User from django.db import models +from django.db.models import F from django.db.models.functions import Lower from django.db.models.signals import post_delete, post_save from django.dispatch import receiver @@ -106,6 +107,17 @@ class MusicGameOrder(models.Model): player = models.ForeignKey(User, on_delete=models.CASCADE) music_video = models.ForeignKey(MusicVideo, on_delete=models.CASCADE) order = models.PositiveIntegerField() + value = models.PositiveIntegerField(default=0) + + def update_value(self): + n_right = self.musicgameanswer_set.filter(game__player=F("answer")).count() + if n_right == 0: + self.value = 1000 + else: + self.value = 1000 / ( + 1 + ((n_right - 1) / (self.game.players.count() - 1)) ** 0.5 + ) + self.save() class Meta: constraints = [ @@ -117,6 +129,17 @@ class MusicGameOrder(models.Model): ordering = ["order"] +class AnswerManager(models.Manager): + def score(self, game, player): + qs = self.filter(game__game=game, game__player=player) + return ( + qs.filter(answer=F("game__player")) + .aggregate(score=models.Sum("game__value", default=0)) + .get("score") + - 500 * qs.exclude(game__player=F("answer")).count() + ) + + class MusicGameAnswer(models.Model): game = models.ForeignKey(MusicGameOrder, on_delete=models.CASCADE) player = models.ForeignKey(User, on_delete=models.CASCADE) @@ -124,6 +147,8 @@ class MusicGameAnswer(models.Model): User, on_delete=models.SET_NULL, null=True, related_name="+" ) + objects = AnswerManager() + class Meta: constraints = [ models.UniqueConstraint(fields=("game", "player"), name="unique_answer"), diff --git a/game/views.py b/game/views.py index b96cb2b..85e7348 100644 --- a/game/views.py +++ b/game/views.py @@ -9,7 +9,7 @@ from django.contrib.auth.models import User from django.contrib.messages.views import SuccessMessageMixin from django.core.exceptions import PermissionDenied from django.db import IntegrityError -from django.db.models import Count, F, Q +from django.db.models import Count, Q from django.shortcuts import get_object_or_404, redirect from django.views import View from django.views.generic import TemplateView @@ -471,33 +471,11 @@ class GameEndView(LoginRequiredMixin, SingleObjectMixin, View): raise PermissionDenied() game.over = True - value = {} for go in game.musicgameorder_set.all(): - value[go.pk] = 1000 / ( - 1 - + ( - (go.musicgameanswer_set.filter(game__player=F("answer")).count()) - - 1 / game.players.count() - ) - ** 2 - ) + go.update_value() for player in game.players.all(): - score = sum( - [ - value[ga.game.pk] - for ga in player.musicgameanswer_set.filter(game__game=game) - .exclude(game__player=player) - .filter(game__player=F("answer")) - ] - ) - score -= ( - 500 - * player.musicgameanswer_set.filter(game__game=game) - .filter(game__player=player) - .exclude(game__player=F("answer")) - .count() - ) + score = player.musicgameanswer_set.score(game, player) models.MusicGameResults.objects.create( game=game, player=player, score=score )