X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=xonstat%2Fmodels%2Fplayer.py;h=89c8cdb7dc1c63bf04ed91c4d5c24bef50c63976;hb=57b24ea2be2032bc46fc248d0ffc29f0258e664c;hp=2564dd3317acd666735a562607d10ff3a34c0905;hpb=2beb927cf6675c89e885c57759238eaefc05fbb0;p=xonotic%2Fxonstat.git diff --git a/xonstat/models/player.py b/xonstat/models/player.py index 2564dd3..89c8cdb 100644 --- a/xonstat/models/player.py +++ b/xonstat/models/player.py @@ -7,8 +7,22 @@ from calendar import timegm from xonstat.models.mixins import FuzzyDateMixin, EpochMixin, NickColorsMixin from xonstat.util import strip_colors, pretty_date, qfont_decode +# Glicko Constants -class Player(EpochMixin, NickColorsMixin): +# the default initial rating value +MU = 1500.0 + +# the default ratings deviation value +PHI = 350.0 + +# the default volatility value +SIGMA = 0.06 + +# the ratio to convert from/to glicko2 +GLICKO2_SCALE = 173.7178 + + +class Player(EpochMixin, NickColorsMixin, FuzzyDateMixin): """ A player, which can represent either a human or a bot. """ @@ -19,10 +33,6 @@ class Player(EpochMixin, NickColorsMixin): else: return strip_colors(self.nick) - # TODO: use FuzzyDateMixin instead, but change the method calls - def joined_pretty_date(self): - return pretty_date(self.create_dt) - def __repr__(self): return "".format(self.player_id, self.nick.encode('utf-8')) @@ -210,4 +220,51 @@ class PlayerMedal(object): """ def __repr__(self): - return "".format(self) + return "".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 = float(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=(float(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 + ) + + def __repr__(self): + return ("".format(self)) + + +class PlayerGlickoBase(PlayerGlicko): + """ + A clone of the above PlayerGlicko class, but created separately in order to avoid + dealing with primary and non-primary SQLAlchemy mappers. + """ + pass \ No newline at end of file