changed up a few things regarding scoring, added some usability features
This commit is contained in:
parent
00d0df4af7
commit
953f2eeb46
22
geogame/main/migrations/0006_auto_20200610_1501.py
Normal file
22
geogame/main/migrations/0006_auto_20200610_1501.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Generated by Django 2.2.4 on 2020-06-10 15:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0005_auto_20200117_0023'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='challenge',
|
||||
name='average',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='challenge',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=255, verbose_name='Challenge Name'),
|
||||
),
|
||||
]
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import random
|
||||
import uuid
|
||||
import math
|
||||
|
||||
from django.contrib.postgres.search import SearchVectorField, SearchQuery, SearchVector
|
||||
from django.conf import settings
|
||||
@ -51,20 +52,14 @@ class User(AbstractUser):
|
||||
|
||||
|
||||
class Challenge(models.Model):
|
||||
name = models.CharField(_('Challenge Name'), max_length=255, blank=False, db_index=True)
|
||||
average = models.PositiveIntegerField(default=0)
|
||||
name = models.CharField(_('Challenge Name'), max_length=255, blank=True, db_index=True)
|
||||
user = models.ForeignKey(User, models.PROTECT,
|
||||
related_name='challenge_user',
|
||||
null=False, blank=False)
|
||||
|
||||
def update_average_score(self):
|
||||
average = GameRound.objects.filter(game__challenge=self).aggregate(Avg('result')).get('result__avg', 0)
|
||||
self.average = average
|
||||
self.save()
|
||||
return average
|
||||
|
||||
def setup_challenge(self, user):
|
||||
rounds = Coord.objects.filter(challenge=self)
|
||||
#setup games with max score
|
||||
game = Game.objects.create(
|
||||
challenge=self,
|
||||
start=timezone.now(),
|
||||
@ -82,6 +77,18 @@ class Challenge(models.Model):
|
||||
round_id = round.id
|
||||
return game.id, round_id
|
||||
|
||||
@property
|
||||
def average(self):
|
||||
#this should be cached, but with low volumes its fine as is
|
||||
return int(round(Game.objects.filter(challenge=self).aggregate(Avg('score')).get('score__avg', 0)))
|
||||
|
||||
@property
|
||||
def num_rounds(self):
|
||||
return Coord.objects.filter(challenge=self).count()
|
||||
|
||||
def num_plays(self):
|
||||
return Game.objects.filter(challenge=self).count()
|
||||
|
||||
|
||||
class Coord(models.Model):
|
||||
lng = models.CharField(_('longitude'), max_length=50, null=False, blank=False)
|
||||
@ -132,5 +139,13 @@ class GameRound(models.Model):
|
||||
else:
|
||||
actual_coord = (self.coord.lat, self.coord.lng,)
|
||||
guess_coord = (self.guess_lat, self.guess_lng,)
|
||||
self.result = distance.distance(actual_coord, guess_coord).km * 1000
|
||||
#get distance in meters between actual coord and the guess
|
||||
dst = distance.distance(actual_coord, guess_coord).km * 1000
|
||||
#calculate a score of 0 to 100
|
||||
if dst < 100:
|
||||
self.result = 100
|
||||
elif dst > 100000:
|
||||
self.result = 0
|
||||
else:
|
||||
self.result = int(round(14.46 * (11.52 - math.log(dst))))
|
||||
super().save(*args, **kwargs)
|
@ -118,6 +118,7 @@ class EditChallengeView(views.UserPassesTestMixin, TemplateView):
|
||||
context['challenge'] = challenge
|
||||
context['formset'] = ChallengeCoordFormSet(queryset=Coord.objects.none())
|
||||
context['coords'] = Coord.objects.filter(challenge=challenge)
|
||||
#add form so users can edit the challenge name
|
||||
return context
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
@ -161,7 +162,7 @@ class ChallengeListView(views.LoginRequiredMixin, ListView):
|
||||
values('challenge').\
|
||||
distinct()
|
||||
|
||||
return Challenge.objects.filter(id__in=ids).order_by('average')
|
||||
return Challenge.objects.filter(id__in=ids).order_by('id')
|
||||
|
||||
|
||||
class NewGameView(views.LoginRequiredMixin, View):
|
||||
@ -241,6 +242,7 @@ class RoundView(views.UserPassesTestMixin, UpdateView):
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RemoveCoordView(View):
|
||||
def post(self, request, *args, **kwargs):
|
||||
round = get_object_or_404(GameRound, pk=self.kwargs.get('round_pk', 0))
|
||||
@ -249,7 +251,7 @@ class RemoveCoordView(View):
|
||||
dodgy_coord.report()
|
||||
|
||||
if game.challenge:
|
||||
round.score = 30000
|
||||
round.score = 100
|
||||
round.guess_lat = 0
|
||||
round.guess_lng = 0
|
||||
round.save()
|
||||
@ -269,7 +271,6 @@ class RemoveCoordView(View):
|
||||
)
|
||||
)
|
||||
else:
|
||||
round.game.challenge.update_average_score()
|
||||
return redirect(
|
||||
reverse_lazy(
|
||||
'game:end-recap-view',
|
||||
@ -320,7 +321,7 @@ class RoundRecapView(views.UserPassesTestMixin, TemplateView):
|
||||
context['guess_lat'] = round.guess_lat
|
||||
context['guess_lng'] = round.guess_lng
|
||||
context['game_id'] = round.game.id
|
||||
context['distance'] = int(round.result)
|
||||
context['result'] = round.result
|
||||
|
||||
next_round = GameRound.objects.filter(
|
||||
game=round.game,
|
||||
@ -328,11 +329,6 @@ class RoundRecapView(views.UserPassesTestMixin, TemplateView):
|
||||
).first()
|
||||
|
||||
if not next_round:
|
||||
#not every game is part of a challenge, so try updated the challenge average
|
||||
try:
|
||||
round.game.challenge.update_average_score()
|
||||
except:
|
||||
pass
|
||||
context['last_round'] = True
|
||||
else:
|
||||
context['next_round_id'] = next_round.id
|
||||
@ -361,14 +357,10 @@ class GameRecapView(views.UserPassesTestMixin, TemplateView):
|
||||
)
|
||||
|
||||
context['results'] = coord_results
|
||||
context['average_distance'] = int(
|
||||
GameRound.objects.filter(game=game)\
|
||||
.aggregate(Avg('result'))\
|
||||
.get('result__avg', 0)
|
||||
)
|
||||
context['total_score'] = game.score
|
||||
# not every game is part of a challenge, so keep this in a try
|
||||
try:
|
||||
context['all_average'] = game.challenge.average
|
||||
context['all_average'] = game.challenge.average()
|
||||
except:
|
||||
pass
|
||||
return context
|
@ -24,7 +24,7 @@ with open(os.path.join(BASE_DIR, "env_secret_key.txt")) as secret_key:
|
||||
SECRET_KEY = secret_key.read().strip()
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
@ -15,12 +15,16 @@
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Average</th>
|
||||
<th>Rounds</th>
|
||||
<th>Plays</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for challenge in challenges %}
|
||||
<tr>
|
||||
<td>{{challenge.name}}</td>
|
||||
<td>{{challenge.average|intcomma}}</td>
|
||||
<td>{{challenge.average}}</td>
|
||||
<td>{{challenge.num_rounds}}</td>
|
||||
<td>{{challenge.num_plays}}</td>
|
||||
<td><a class="btn btn-success btn-block" href="{% url 'game:new-game' %}?challenge={{challenge.id}}" role="button">Play</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
{{ form.non_field_errors }}
|
||||
{% csrf_token %}
|
||||
<div class="form-group form-row">
|
||||
<label for="staticName" class="col-sm-4 col-form-label">Name</label>
|
||||
<label for="staticName" class="col-sm-4 col-form-label">Challenge Name</label>
|
||||
<div class="col-sm-8">
|
||||
{{form.name}}
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="alert alert-info">
|
||||
Your average guess was {{average_distance|intcomma}}m away.{% if all_average %} The average for this challenge is {{all_average|intcomma}}m{%endif%}
|
||||
Your total score was {{total_score}}.{% if all_average %} The average for this challenge is {{all_average}}{%endif%}
|
||||
</div>
|
||||
|
||||
<div id="map" class="guessMap"></div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="alert alert-info">
|
||||
Your guess was {{distance|intcomma}}m away.
|
||||
You scored {{result}} out of 100.
|
||||
</div>
|
||||
|
||||
<div id="map" class="guessMap"></div>
|
||||
|
@ -6,6 +6,7 @@ django-allauth==0.39.1
|
||||
django-autocomplete-light==3.4.1
|
||||
django-braces==1.13.0
|
||||
django-countries==5.4
|
||||
django-dynamic-formsets==0.0.8
|
||||
django-extensions==2.2.1
|
||||
django-starfield==1.0.post1
|
||||
geographiclib==1.49
|
||||
|
Loading…
Reference in New Issue
Block a user