Add MusicGameResults model and score calculation logic in GameEndView

This commit is contained in:
Edgar P. Burkhart 2025-06-15 13:34:37 +02:00
parent b1ec960dfa
commit 303538bf48
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
7 changed files with 116 additions and 18 deletions

View file

@ -160,4 +160,10 @@ table select {
color: var(--pico-color-sand-300);
}
}
.score {
font-weight: 900;
color: var(--pico-color-zinc-500);
margin-left: .5em;
}
}

View file

@ -1,16 +0,0 @@
# Generated by Django 5.2.3 on 2025-06-15 10:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("game", "0019_alter_musikgame_options_musikgame_over"),
]
operations = [
migrations.AlterModelOptions(
name="musikgame",
options={"ordering": ["over", "-date"]},
),
]

View file

@ -0,0 +1,55 @@
# Generated by Django 5.2.3 on 2025-06-15 11:23
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("game", "0019_alter_musikgame_options_musikgame_over"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterModelOptions(
name="musikgame",
options={"ordering": ["over", "-date"]},
),
migrations.CreateModel(
name="MusicGameResults",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("score", models.PositiveIntegerField(default=0)),
(
"game",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="game.musikgame"
),
),
(
"player",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"ordering": ["-score"],
"constraints": [
models.UniqueConstraint(
fields=("game", "player"), name="unique_result"
)
],
},
),
]

View file

@ -0,0 +1,17 @@
# Generated by Django 5.2.3 on 2025-06-15 11:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("game", "0020_alter_musikgame_options_musicgameresults"),
]
operations = [
migrations.AlterField(
model_name="musicgameresults",
name="score",
field=models.IntegerField(default=0),
),
]

View file

@ -129,3 +129,15 @@ class MusicGameAnswer(models.Model):
models.UniqueConstraint(fields=("game", "player"), name="unique_answer"),
]
ordering = ["game"]
class MusicGameResults(models.Model):
game = models.ForeignKey(MusikGame, on_delete=models.CASCADE)
player = models.ForeignKey(User, on_delete=models.CASCADE)
score = models.IntegerField(default=0)
class Meta:
constraints = [
models.UniqueConstraint(fields=("game", "player"), name="unique_result")
]
ordering = ["-score"]

View file

@ -35,7 +35,11 @@
</h2>
{% if musikgame.over %}
<ol class="podium">
{% for player in musikgame.players.all %}<li>{{ player.username }}</li>{% endfor %}
{% for player in musikgame.musicgameresults_set.all %}
<li>
{{ player.player.username }} <span class="score">{{ player.score }}</span>
</li>
{% endfor %}
</ol>
{% else %}
<p>{{ musikgame.players.all|join:", " }}</p>

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, Q
from django.db.models import Count, F, Q
from django.shortcuts import get_object_or_404, redirect
from django.views import View
from django.views.generic import TemplateView
@ -468,5 +468,25 @@ class GameEndView(LoginRequiredMixin, SingleObjectMixin, View):
if not game.group.is_leader(request.user):
raise PermissionDenied()
game.over = True
for player in game.players.all():
score = (
100
* player.musicgameanswer_set.filter(game__game=game)
.exclude(game__player=player)
.filter(game__player=F("answer"))
.count()
)
score -= (
50
* player.musicgameanswer_set.filter(game__game=game)
.filter(game__player=player)
.exclude(game__player=F("answer"))
.count()
)
models.MusicGameResults.objects.create(
game=game, player=player, score=score
)
game.save()
return redirect("game_detail", pk)