Add value field to MusicGameOrder and update score calculation logic

This commit is contained in:
Edgar P. Burkhart 2025-06-15 15:09:48 +02:00
parent 178a7cab03
commit 92abcb584c
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
3 changed files with 45 additions and 25 deletions

View file

@ -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),
),
]

View file

@ -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"),

View file

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