Add value field to MusicGameOrder and update score calculation logic
This commit is contained in:
parent
178a7cab03
commit
92abcb584c
3 changed files with 45 additions and 25 deletions
17
game/migrations/0022_musicgameorder_value.py
Normal file
17
game/migrations/0022_musicgameorder_value.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,5 +1,6 @@
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import F
|
||||||
from django.db.models.functions import Lower
|
from django.db.models.functions import Lower
|
||||||
from django.db.models.signals import post_delete, post_save
|
from django.db.models.signals import post_delete, post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
@ -106,6 +107,17 @@ class MusicGameOrder(models.Model):
|
||||||
player = models.ForeignKey(User, on_delete=models.CASCADE)
|
player = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
music_video = models.ForeignKey(MusicVideo, on_delete=models.CASCADE)
|
music_video = models.ForeignKey(MusicVideo, on_delete=models.CASCADE)
|
||||||
order = models.PositiveIntegerField()
|
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:
|
class Meta:
|
||||||
constraints = [
|
constraints = [
|
||||||
|
@ -117,6 +129,17 @@ class MusicGameOrder(models.Model):
|
||||||
ordering = ["order"]
|
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):
|
class MusicGameAnswer(models.Model):
|
||||||
game = models.ForeignKey(MusicGameOrder, on_delete=models.CASCADE)
|
game = models.ForeignKey(MusicGameOrder, on_delete=models.CASCADE)
|
||||||
player = models.ForeignKey(User, 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="+"
|
User, on_delete=models.SET_NULL, null=True, related_name="+"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
objects = AnswerManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
constraints = [
|
constraints = [
|
||||||
models.UniqueConstraint(fields=("game", "player"), name="unique_answer"),
|
models.UniqueConstraint(fields=("game", "player"), name="unique_answer"),
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.contrib.auth.models import User
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import IntegrityError
|
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.shortcuts import get_object_or_404, redirect
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
@ -471,33 +471,11 @@ class GameEndView(LoginRequiredMixin, SingleObjectMixin, View):
|
||||||
raise PermissionDenied()
|
raise PermissionDenied()
|
||||||
game.over = True
|
game.over = True
|
||||||
|
|
||||||
value = {}
|
|
||||||
for go in game.musicgameorder_set.all():
|
for go in game.musicgameorder_set.all():
|
||||||
value[go.pk] = 1000 / (
|
go.update_value()
|
||||||
1
|
|
||||||
+ (
|
|
||||||
(go.musicgameanswer_set.filter(game__player=F("answer")).count())
|
|
||||||
- 1 / game.players.count()
|
|
||||||
)
|
|
||||||
** 2
|
|
||||||
)
|
|
||||||
|
|
||||||
for player in game.players.all():
|
for player in game.players.all():
|
||||||
score = sum(
|
score = player.musicgameanswer_set.score(game, player)
|
||||||
[
|
|
||||||
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()
|
|
||||||
)
|
|
||||||
models.MusicGameResults.objects.create(
|
models.MusicGameResults.objects.create(
|
||||||
game=game, player=player, score=score
|
game=game, player=player, score=score
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue