Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #84 from cvicentiu/challengeStat

Challenge statistics, helping fraud detection, thanks Vicentiu
  • Loading branch information...
commit 2f528f6a81317b21034369da95269da5ea5eab8a 2 parents 9c65973 + c06d2e9
Alex Eftimie alexef authored
5 wouso/games/challenge/templates/challenge/index.html
View
@@ -18,10 +18,11 @@
</p>
{% else %}
<p>{% trans 'To launch a challenge, find the player you want to challenge and click on the <em>Challenge</em> button, next to his profile.' %}</p>
-<a href="{% url challenge_random %}">Challenge random player</a>
+<a href="{% url challenge_random %}">Challenge random player</a> <br>
+
{% endif %}
{% endif %}
-
+<a href="{% url challenge_stats %}">View Challenge Statistics</a>
<h3>{% trans 'Active' %}</h3>
<ul class="answers">
{% for c in challenges %}
36 wouso/games/challenge/templates/challenge/statistics.html
View
@@ -0,0 +1,36 @@
+{% extends 'interface/section_base.html' %}
+{% load i18n %}
+{% block title %}{% trans 'Challenges' %}{% endblock %}
+{% block sectiontitle %}{% trans 'Challenge statistics' %}{% endblock %}
+
+{% block sectioncontent %}
+
+<p> {% trans 'Challenges played: ' %} {{n_chall_played }}</p>
+<p> {% trans 'Challenges won: ' %} {{ n_chall_won }}</p>
+<p> {% trans 'Challenges sent: ' %} {{ n_chall_sent }}</p>
+<p> {% trans 'Challenges received: ' %} {{ n_chall_rec }}</p>
+<p> {% trans 'Challenges refused: ' %} {{ n_chall_ref }}</p>
+<p> {% trans 'Win percentage: ' %} {{ win_percentage }}%</p>
+<p> {% trans 'Average time taken: ' %} {{ average_time }} {% trans 's' %} </p>
+<p> {% trans 'Average score: ' %} {{ average_score }} </p>
+<table>
+ <tr align=center>
+ <td><b>Opponent</b></td>
+ <td><b>Won</b></td>
+ <td><b>Lost</b></td>
+ <td><b>Draw</b></td>
+ <td><b>Refused</b></td>
+ <td><b>Total</b></td>
+ </tr>
+{% for op in opponents %}
+ <tr align=center>
+ <td><a href="{% url detailed_challenge_stats op.0.id %}">{{op.0.nickname}}</a></td>
+ <td>{{op.1}}</td>
+ <td>{{op.2}}</td>
+ <td>{{op.3}}</td>
+ <td>{{op.4}}</td>
+ <td>{{op.5}}</td>
+ </tr>
+{% endfor %}
+</table>
+{% endblock %}
47 wouso/games/challenge/templates/challenge/statistics_detail.html
View
@@ -0,0 +1,47 @@
+{% extends 'interface/section_base.html' %}
+{% load i18n %}
+{% block title %}
+ {% trans 'Statistics ' %}{{current_player}} - {{target_player}}
+{% endblock %}
+{% block sectiontitle %}{% trans 'Challenges against '%}{{ opponent }}
+{% endblock %}
+{% block sectioncontent %}
+<table>
+ <tr align=center>
+ <td><b> {% trans 'Date' %} </b> </td>
+ <td><b> {% trans 'Result' %} </b> </td>
+ <td><b> {% trans 'Time played' %} </b> </td>
+ <td><b> {% trans 'Score Self' %} </b> </td>
+ <td><b> {% trans 'Opponent time played' %} </b></td>
+ <td><b> {% trans 'Score Opponent' %} </b> </td>
+ </tr>
+ {% for c in chall_total %}
+ <tr align=center>
+ <td> {{ c.date }} </td>
+ <td> {% if c.status == "D" %} <font color=grey>Draw</font>
+ {% else %} {% if c.status == "P" %}
+ {% if c.winner == current_player %}<font color=green>Won</font>
+ {% else %} <font color=red>Lost</font> {% endif %}
+ {% else %} {% if c.status == "R" %} Refused
+ {% else %} Pending [{{ c.status }}]{% endif %}
+ {% endif %}
+ {% endif %} </td>
+ <!-- This seems like it's too tightly coupled
+ with the implementation -->
+ {% if c.user_from.user == current_player %}
+ <td>{{c.user_from.seconds_took}}</td>
+ <td>{{c.user_from.score}}</td>
+ <td>{{c.user_to.seconds_took}}</td>
+ <td>{{c.user_to.score}}</td>
+ {% else %}
+ <td>{{c.user_to.seconds_took}}</td>
+ <td>{{c.user_to.score}}</td>
+ <td>{{c.user_from.seconds_took}}</td>
+ <td>{{c.user_from.score}}</td>
+ {% endif %}
+ <!-- fix? -->
+ </tr>
+ {% endfor %}
+</table>
+<center><a href="javascript:history.go(-1)">Return</a></center>
+{% endblock %}
3  wouso/games/challenge/urls.py
View
@@ -14,4 +14,7 @@
url(r'^history/(?P<playerid>\d+)/$', 'history', name='chellenge_history'),
url(r'^randomchallenge/$', 'challenge_random', name='challenge_random'),
+ url(r'^stats/$', 'challenge_stats', name='challenge_stats'),
+ url(r'^stats/(?P<target_id>\d+)/', 'detailed_challenge_stats',
+ name='detailed_challenge_stats'),
)
78 wouso/games/challenge/views.py
View
@@ -231,3 +231,81 @@ def challenge_random(request):
return launch(request, players[i].id)
+@login_required
+def detailed_challenge_stats(request, target_id):
+ """Statistics for one pair of users, current_player and target_id"""
+ current_player = request.user.get_profile().get_extension(ChallengeUser)
+
+ target_user = get_object_or_404(ChallengeUser, user__id=target_id)
+
+ from django.db.models import Q, Count
+ chall_total = Challenge.objects.filter(Q(user_from__user = current_player) |
+ Q(user_to__user = current_player)).exclude(status=u'L')
+
+ chall_total = chall_total.filter(Q(user_from__user=target_user) |
+ Q(user_to__user=target_user)).order_by('-date')
+
+ return render_to_response('challenge/statistics_detail.html',
+ {'current_player' : current_player, 'target_player' : target_user,
+ 'chall_total' : chall_total,
+ 'opponent' : target_user},
+ context_instance=RequestContext(request))
+
+@login_required
+def challenge_stats(request):
+ """Statistics for one user"""
+ current_player = request.user.get_profile().get_extension(ChallengeUser)
+
+ from django.db.models import Avg, Q, Count
+ chall_total = Challenge.objects.filter(Q(user_from__user=current_player) |
+ Q(user_to__user=current_player)).exclude(status=u'L')
+ chall_sent = chall_total.filter(user_from__user=current_player)
+ chall_rec = chall_total.filter(user_to__user=current_player)
+ chall_won = chall_total.filter(winner=current_player)
+
+ n_chall_sent = chall_sent.count()
+ n_chall_rec = chall_rec.count()
+ n_chall_played = chall_sent.count() + chall_rec.count()
+ n_chall_won = chall_won.count()
+ n_chall_ref = chall_total.filter(status=u'R').count()
+ all_participation = Participant.objects.filter(user = current_player)
+
+ opponents_from = list(set(map(lambda x : x.user_to.user, chall_sent)))
+ opponents_to = list(set(map(lambda x : x.user_from.user, chall_rec)))
+ opponents = list(set(opponents_from + opponents_to))
+
+ result = []
+
+ for op in opponents:
+ chall_against_op = chall_total.filter(Q(user_to__user=op) |
+ Q(user_from__user=op))
+ won = chall_against_op.filter(Q(status=u'P') & Q(winner=current_player)).count()
+ lost = chall_against_op.filter(Q(status=u'P') & Q(winner=op)).count()
+ draw = chall_against_op.filter(Q(status=u'D')).count()
+ refused = chall_against_op.filter(Q(status=u'R')).count()
+ total = won + lost + draw + refused
+ result.append((op, won, lost, draw, refused, total))
+
+ result.sort(key=lambda by:by[5], reverse=True) #sort by total
+
+ average_time = all_participation.aggregate(Avg('seconds_took'))['seconds_took__avg']
+ average_score = all_participation.aggregate(Avg('score'))['score__avg']
+
+ if average_time == None : average_time = 0
+ if average_score == None : average_score = 0
+
+ win_percentage = 0
+ if n_chall_played > 0:
+ win_percentage = float(n_chall_won) / n_chall_played * 100
+
+ #pretty print the float for the template
+ win_percentage = '%.1f' % win_percentage
+
+ return render_to_response('challenge/statistics.html',
+ {'n_chall_played' : n_chall_played, 'n_chall_won' : n_chall_won,
+ 'n_chall_sent' : n_chall_sent, 'n_chall_rec' : n_chall_rec,
+ 'n_chall_ref' : n_chall_ref, 'win_percentage' : win_percentage,
+ 'average_time' : average_time, 'average_score' : average_score,
+ 'current_player' : current_player, 'opponents' : result
+ },
+ context_instance=RequestContext(request))
Please sign in to comment.
Something went wrong with that request. Please try again.