return k\r
\r
\r
-# For team games where multiple scores and elos are at play, the elos\r
-# must be adjusted according to their strength relative to the player\r
-# in the next-lowest scoreboard position.\r
-def update(elos, ep):\r
- for x in elos:\r
- if x.elo == None:\r
- x.elo = ep.initial\r
- x.eloadjust = 0\r
- if len(elos) < 2:\r
- return elos\r
- for i in xrange(0, len(elos)):\r
- ei = elos[i]\r
- for j in xrange(i+1, len(elos)):\r
- ej = elos[j]\r
- si = ei.score\r
- sj = ej.score\r
-\r
- # normalize scores\r
- ofs = min(0, si, sj)\r
- si -= ofs\r
- sj -= ofs\r
- if si + sj == 0:\r
- si, sj = 1, 1 # a draw\r
-\r
- # real score factor\r
- scorefactor_real = si / float(si + sj)\r
-\r
- # estimated score factor by elo\r
- elodiff = min(ep.maxlogdistance, max(-ep.maxlogdistance, (ei.elo - ej.elo) * ep.logdistancefactor))\r
- scorefactor_elo = 1 / (1 + math.exp(-elodiff))\r
-\r
- # how much adjustment is good?\r
- # scorefactor(elodiff) = 1 / (1 + e^(-elodiff * logdistancefactor))\r
- # elodiff(scorefactor) = -ln(1/scorefactor - 1) / logdistancefactor\r
- # elodiff'(scorefactor) = 1 / ((scorefactor) (1 - scorefactor) logdistancefactor)\r
- # elodiff'(scorefactor) >= 4 / logdistancefactor\r
-\r
- # adjust'(scorefactor) = K1 + K2\r
-\r
- # so we want:\r
- # K1 + K2 <= 4 / logdistancefactor <= elodiff'(scorefactor)\r
- # as we then don't overcompensate\r
-\r
- adjustment = scorefactor_real - scorefactor_elo\r
- ei.eloadjust += adjustment\r
- ej.eloadjust -= adjustment\r
- for x in elos:\r
- x.elo = max(x.elo + x.eloadjust * x.k * ep.global_K / float(len(elos) - 1), ep.floor)\r
- x.games += 1\r
- return elos\r
-\r
-\r
# parameters for K reduction\r
# this may be touched even if the DB already exists\r
KREDUCTION = KReduction(600, 120, 0.5, 0, 32, 0.2)\r
# only global_K may be touched even if the DB already exists\r
# we start at K=200, and fall to K=40 over the first 20 games\r
ELOPARMS = EloParms(global_K = 200)\r
-\r