commit 972e2af4bbf850f03de2459ef45470f91b412069
parent 10c4d0f280921a79b3c89e44b41bd1eb39d49ede
Author: Étienne Simon <esimon@esimon.eu>
Date: Sun, 3 May 2015 19:34:35 +0000
Commenting
Diffstat:
M | rank.py | | | 28 | +++++++++++++++++++++++++--- |
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/rank.py b/rank.py
@@ -13,13 +13,27 @@ sys.path.insert(0, '/root/sadm/python-lib')
from django.contrib.auth.models import User
from prologin.concours.stechec.models import *
-sample_size = 1
+# Number of players per game
party_size = 4
+
+# Quality of sampling new members for a party
+sample_size = 1
+
+# The conservative score (aka "at least this good") is : mean - conservativeness * stddev
conservativeness = 3
+
+# Number of matches running at the same time
max_concurrent_matches = 250
+
+# Maximum number of simultaneous matches per player
concurrent_match_per_player = 50
+
+# Maximum difference in number of concurrent matches between the player who is playing the most and the one who is playing the least
min_ppp_margin = 2
+
+# Frequency (in number of launched games) at which game results are gathered
update_score_frequency = 100
+
tournament_name='Tournoi final'
filepath=sys.argv[1]
@@ -31,6 +45,7 @@ nb_match_per_player = {}
champions = {}
users = {}
for user in ratings.keys():
+ # The last non deleted champion of a user
champion = Champion.objects.filter(author__username=user).order_by('-ts').exclude(deleted=True)[0].pk
nb_match_per_player[user] = 0
champions[user] = champion
@@ -77,21 +92,26 @@ def can_enter_match(user):
return nb_match_per_player[user] < concurrent_match_per_player
def match_making():
+ # Number of game of the player who is playing the least
min_ppp = min(nb_match_per_player.values())
pick_from_me = [ user for user in ratings.keys() if nb_match_per_player[user] <= min_ppp + min_ppp_margin]
ready = list(filter(can_enter_match, ratings.keys()))
+
+ # The player with the most uncertain rating, he'll be in the party no matter what
fuzziest = max(pick_from_me, key=lambda x: ratings[x].sigma)
ready.remove(fuzziest)
- sample_me = []
+ # Fill sample_me with available ("ready") players, the remaining (party_size-1) players to be picked will be consecutive players in this array
+ # The //x*x is done so that sample_me is extend with arrays of size multiple of (party_size-1), this mean we can't sample a party from two different shuffled ready arrays, since doing so might result in a match with the same player appearing twice
+ sample_me = []
for _ in range(sample_size):
shuffle(ready)
sample_me += ready[:len(ready)//(party_size-1)*(party_size-1)]
+ # We pick the remaining (party_size-1) players from sample_me to maximize the match quality
max_qual = -1
max_party = None
-
for i in range(len(sample_me)//(party_size-1)):
party_minus_1 = sample_me[(party_size-1)*i:(party_size-1)*(i+1)]
party = party_minus_1 + [ fuzziest ]
@@ -104,6 +124,7 @@ def match_making():
return max_party
+# update ratings given the result of a match in a dictionary {user: score}
def update(scores):
for key in scores:
nb_match_per_player[key] -= 1
@@ -119,6 +140,7 @@ def update(scores):
with open(filepath, 'wb') as f:
pickle.dump(ratings, f)
+# Check if any matches finished and update ratings accordingly
def update_scores():
global current_matches
remove_me = []