]> git.xonotic.org Git - xonotic/xonstat.git/commitdiff
Move the model class to the right place, add Xon-specific fields.
authorAnt Zucaro <azucaro@gmail.com>
Tue, 19 Dec 2017 19:35:20 +0000 (14:35 -0500)
committerAnt Zucaro <azucaro@gmail.com>
Tue, 19 Dec 2017 19:35:20 +0000 (14:35 -0500)
xonstat/glicko.py
xonstat/models/player.py

index 8ed57221fcfff6a8f5b7d5e5d9b9eec90c013a8c..aa002a900a90135b84064b85dd7f086968e82b68 100644 (file)
@@ -2,50 +2,17 @@ import logging
 import math
 import sys
 
+from xonstat.models import PlayerGlicko
+
 log = logging.getLogger(__name__)
 
 # DEBUG
 # log.addHandler(logging.StreamHandler())
 # log.setLevel(logging.DEBUG)
 
-# the default initial rating value
-MU = 1500
-
-# the default ratings deviation value
-PHI = 350
-
-# the default volatility value
-SIGMA = 0.06
-
 # the default system volatility constant
 TAU = 0.3
 
-# the ratio to convert from/to glicko2
-GLICKO2_SCALE = 173.7178
-
-
-class PlayerGlicko(object):
-    def __init__(self, mu=MU, phi=PHI, sigma=SIGMA):
-        self.mu = mu
-        self.phi = phi
-        self.sigma = sigma
-
-    def to_glicko2(self):
-        """ Convert a rating to the Glicko2 scale. """
-        return PlayerGlicko(
-            mu=(self.mu - MU) / GLICKO2_SCALE,
-            phi=self.phi / GLICKO2_SCALE,
-            sigma=self.sigma
-        )
-
-    def from_glicko2(self):
-        """ Convert a rating to the original Glicko scale. """
-        return PlayerGlicko(
-            mu=self.mu * GLICKO2_SCALE + MU,
-            phi=self.phi * GLICKO2_SCALE,
-            sigma=self.sigma
-        )
-
 
 def calc_g(phi):
     return 1 / math.sqrt(1 + (3 * phi ** 2) / (math.pi ** 2))
@@ -148,7 +115,8 @@ def rate(player, opponents, results):
 
     mu_bar = p_g2.mu + phi_bar**2 * sum_terms
 
-    new_rating = PlayerGlicko(mu_bar, phi_bar, sigma_bar).from_glicko2()
+    new_rating = PlayerGlicko(player.player_id, player.game_type_cd, player.category, mu_bar,
+                              phi_bar, sigma_bar).from_glicko2()
 
     # DEBUG
     # log.debug("v={}".format(v))
@@ -163,10 +131,11 @@ def rate(player, opponents, results):
 
 
 def main():
-    pA = PlayerGlicko(mu=1500, phi=200)
-    pB = PlayerGlicko(mu=1400, phi=30)
-    pC = PlayerGlicko(mu=1550, phi=100)
-    pD = PlayerGlicko(mu=1700, phi=300)
+    # the example in the actual Glicko2 paper, for verification purposes
+    pA = PlayerGlicko(1, "duel", mu=1500, phi=200)
+    pB = PlayerGlicko(2, "duel", mu=1400, phi=30)
+    pC = PlayerGlicko(3, "duel", mu=1550, phi=100)
+    pD = PlayerGlicko(4, "duel", mu=1700, phi=300)
 
     opponents = [pB, pC, pD]
     results = [1, 0, 0]
@@ -175,4 +144,4 @@ def main():
 
 
 if __name__ == "__main__":
-    sys.exit(main())
+     sys.exit(main())
index d9df0759d628a8d3bbb06a30dfcc9fa745e442f6..655aa5ce9956526e59025b89c98e83994c82ba43 100644 (file)
@@ -7,6 +7,20 @@ from calendar import timegm
 from xonstat.models.mixins import FuzzyDateMixin, EpochMixin, NickColorsMixin
 from xonstat.util import strip_colors, pretty_date, qfont_decode
 
+# Glicko Constants
+
+# the default initial rating value
+MU = 1500
+
+# the default ratings deviation value
+PHI = 350
+
+# the default volatility value
+SIGMA = 0.06
+
+# the ratio to convert from/to glicko2
+GLICKO2_SCALE = 173.7178
+
 
 class Player(EpochMixin, NickColorsMixin, FuzzyDateMixin):
     """
@@ -207,3 +221,38 @@ class PlayerMedal(object):
 
     def __repr__(self):
         return "<PlayerMedal(pid={0.player_id}, place={0.place}, alt={0.alt})>".format(self)
+
+
+class PlayerGlicko(object):
+    """
+    A player's skill for a particular game type, as determined by the Glicko2 algorithm.
+    """
+    def __init__(self, player_id, game_type_cd, category="general", mu=MU, phi=PHI, sigma=SIGMA):
+        self.player_id = player_id
+        self.game_type_cd = game_type_cd
+        self.category = category
+        self.mu = mu
+        self.phi = phi
+        self.sigma = sigma
+
+    def to_glicko2(self):
+        """ Convert a rating to the Glicko2 scale. """
+        return PlayerGlicko(
+            player_id=self.player_id,
+            game_type_cd=self.game_type_cd,
+            category=self.category,
+            mu=(self.mu - MU) / GLICKO2_SCALE,
+            phi=self.phi / GLICKO2_SCALE,
+            sigma=self.sigma
+        )
+
+    def from_glicko2(self):
+        """ Convert a rating to the original Glicko scale. """
+        return PlayerGlicko(
+            player_id=self.player_id,
+            game_type_cd=self.game_type_cd,
+            category=self.category,
+            mu=self.mu * GLICKO2_SCALE + MU,
+            phi=self.phi * GLICKO2_SCALE,
+            sigma=self.sigma
+        )
\ No newline at end of file