6 def __init__(self, global_K = 15, initial = 100, floor = 100, logdistancefactor = math.log(10)/float(400), maxlogdistance = math.log(10)):
\r
7 self.global_K = global_K
\r
8 self.initial = initial
\r
10 self.logdistancefactor = logdistancefactor
\r
11 self.maxlogdistance = maxlogdistance
\r
15 def __init__(self, fulltime, mintime, minratio, games_min, games_max, games_factor):
\r
16 self.fulltime = fulltime
\r
17 self.mintime = mintime
\r
18 self.minratio = minratio
\r
19 self.games_min = games_min
\r
20 self.games_max = games_max
\r
21 self.games_factor = games_factor
\r
23 def eval(self, mygames, mytime, matchtime):
\r
24 if mytime < self.mintime:
\r
26 if mytime < self.minratio * matchtime:
\r
28 if mytime < self.fulltime:
\r
29 k = mytime / float(self.fulltime)
\r
32 if mygames >= self.games_max:
\r
33 k *= self.games_factor
\r
34 elif mygames > self.games_min:
\r
35 k *= 1.0 - (1.0 - self.games_factor) * (mygames - self.games_min) / float(self.games_max - self.games_min)
\r
39 # For team games where multiple scores and elos are at play, the elos
\r
40 # must be adjusted according to their strength relative to the player
\r
41 # in the next-lowest scoreboard position.
\r
42 def update(elos, ep):
\r
49 for i in xrange(0, len(elos)):
\r
51 for j in xrange(i+1, len(elos)):
\r
57 ofs = min(0, si, sj)
\r
61 si, sj = 1, 1 # a draw
\r
64 scorefactor_real = si / float(si + sj)
\r
66 # estimated score factor by elo
\r
67 elodiff = min(ep.maxlogdistance, max(-ep.maxlogdistance, (ei.elo - ej.elo) * ep.logdistancefactor))
\r
68 scorefactor_elo = 1 / (1 + math.exp(-elodiff))
\r
70 # how much adjustment is good?
\r
71 # scorefactor(elodiff) = 1 / (1 + e^(-elodiff * logdistancefactor))
\r
72 # elodiff(scorefactor) = -ln(1/scorefactor - 1) / logdistancefactor
\r
73 # elodiff'(scorefactor) = 1 / ((scorefactor) (1 - scorefactor) logdistancefactor)
\r
74 # elodiff'(scorefactor) >= 4 / logdistancefactor
\r
76 # adjust'(scorefactor) = K1 + K2
\r
79 # K1 + K2 <= 4 / logdistancefactor <= elodiff'(scorefactor)
\r
80 # as we then don't overcompensate
\r
82 adjustment = scorefactor_real - scorefactor_elo
\r
83 ei.eloadjust += adjustment
\r
84 ej.eloadjust -= adjustment
\r
86 x.elo = max(x.elo + x.eloadjust * x.k * ep.global_K / float(len(elos) - 1), ep.floor)
\r
91 # parameters for K reduction
\r
92 # this may be touched even if the DB already exists
\r
93 KREDUCTION = KReduction(600, 120, 0.5, 0, 32, 0.2)
\r
95 # parameters for chess elo
\r
96 # only global_K may be touched even if the DB already exists
\r
97 # we start at K=200, and fall to K=40 over the first 20 games
\r
98 ELOPARMS = EloParms(global_K = 200)
\r