-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelo.py
72 lines (55 loc) · 2.04 KB
/
elo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#ELO
#python 3.4.3
import math
class ELOPlayer:
name = ""
place = 0
eloPre = 0
eloPost = 0
eloChange = 0
class ELOMatch:
def __init__(self):
self.players = []
def clearMatch(self):
self.players = []
def addPlayer(self, name, place, elo):
player = ELOPlayer()
player.name = name
player.place = place
player.eloPre = elo
self.players.append(player)
def getELO(self, name):
for p in self.players:
if p.name == name:
return p.eloPost
return 1500
def getELOChange(self, name):
for p in self.players:
if p.name == name:
return p.eloChange
return 0
def calculateELOs(self):
n = len(self.players)
K = 32 / (n - 1) #where the two is make sure to change it back to n
for player in self.players:
curPlace = player.place
curELO = player.eloPre
for opponent in self.players:
if player == opponent:
continue
opponentPlace = opponent.place
opponentELO = opponent.eloPre
#work out S
if curPlace < opponentPlace:
S = 1.0
elif curPlace == opponentPlace:
S = 0.5
else:
S = 0.0
#work out EA
EA = 1 / (1.0 + math.pow(10.0, (opponentELO - curELO) / 400.0))
#calculate ELO change vs this one opponent, add it to our change bucket
#I currently round at this point, this keeps rounding changes symetrical between EA and EB, but changes K more than it should
player.eloChange += round(K * (S - EA))
#add accumulated change to initial ELO for final ELO
player.eloPost = player.eloPre + player.eloChange