From 79964e9438191a539b7186c5a3b5ef71bf3394af Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Tue, 4 Jun 2019 23:17:11 +0200 Subject: [PATCH] continue refactor --- NetworkParser.py | 6 +-- Player.py | 6 +-- Round.py | 4 +- StorrageBackend.py | 73 +++++++++++++++++++--------------- TrueSkillWrapper.py | 97 +++++++++++++++------------------------------ 5 files changed, 83 insertions(+), 103 deletions(-) diff --git a/NetworkParser.py b/NetworkParser.py index c4a4c6e..79da018 100644 --- a/NetworkParser.py +++ b/NetworkParser.py @@ -95,7 +95,7 @@ def get_rebuild_team(string): p = DummyPlayer(pair.split("|")[0]); players += [p] players = list(map(players,lambda p: SB.known_players[p])) - players = sorted(players,key=lambda x: TS.get_env().expose(x.rating),reverse=True) + players = sorted(players,key=lambda x: TS.getEnviroment().expose(x.rating),reverse=True) count = 0 # initial # @@ -154,14 +154,14 @@ def parse_teams(data): if tmp in SB.known_players: ret[0].update({SB.known_players[tmp]:Storrage.known_players[tmp].rating}) else: - ret[0].update({tmp:TS.new_rating()}) + ret[0].update({tmp:TS.newRating()}) for sid in team2: sid = sid.strip() tmp = Player.DummyPlayer(sid, sid) if tmp in SB.known_players: ret[1].update({SB.known_players[tmp]:Storrage.known_players[tmp].rating}) else: - ret[1].update({tmp:TS.new_rating()}) + ret[1].update({tmp:TS.newRating()}) return ret def parse_players(data, lol=False): diff --git a/Player.py b/Player.py index 0bd143a..1f68fc5 100644 --- a/Player.py +++ b/Player.py @@ -6,7 +6,7 @@ class Player: if rating: self.rating = rating else: - self.rating = TS.new_rating() + self.rating = TS.newRating() self.steamid = steamid self.cur_name = name def __hash__(self): @@ -25,7 +25,7 @@ class Player: class DummyPlayer(Player): def __init__(self, steamid, name="PLACEHOLDER", rating=None): - self.rating = TS.new_rating() + self.rating = TS.newRating() if rating: self.rating = rating self.name = name @@ -37,7 +37,7 @@ class PlayerInRound(Player): self.name = name self.cur_name = name self.steamid = steamid - self.rating = TS.new_rating() + self.rating = TS.newRating() self.active_time = datetime.timedelta(0) if type(team) != int or team > 3 or team < 0: raise Exception("Invalid TeamID '{}', must be 0-3 (inkl.)".format(team)) diff --git a/Round.py b/Round.py index 4c444db..1126fd5 100644 --- a/Round.py +++ b/Round.py @@ -140,11 +140,11 @@ class Round: for pStr in winnersStr.split(","): if pStr == "": continue - winners.update({PlayerInRound.deserialize(pStr):TS.new_rating()}) + winners.update({PlayerInRound.deserialize(pStr):TS.newRating()}) for pStr in losersStr.split(","): if pStr == "": continue - losers.update({PlayerInRound.deserialize(pStr):TS.new_rating()}) + losers.update({PlayerInRound.deserialize(pStr):TS.newRating()}) startTime = datetime.strptime(startTimeStr, "%y %b %d %H:%M:%S") duration = timedelta(seconds=int(duration)) return Round(winners, losers, _map, duration, startTime, winner_side) diff --git a/StorrageBackend.py b/StorrageBackend.py index 1b06b65..2577022 100644 --- a/StorrageBackend.py +++ b/StorrageBackend.py @@ -33,9 +33,7 @@ def save_to_file(fname="score.log"): def sync_from_database(players): for p in players: - #print("BKnP: {}".format(p)) if p in known_players: - #print("KnP: {}".format(p)) p.rating = known_players[p].rating if type(players) == dict: players[p] = p.rating @@ -65,7 +63,7 @@ def updatePlayerRanks(force=False): if force or last_rank_update - datetime.now() > timedelta(seconds=240): last_rank_update = datetime.now() - s = sorted(known_players.values(), key=lambda x: TS.get_env().expose(x.rating),reverse=True) + s = sorted(known_players.values(), key=lambda x: TS.getEnviroment().expose(x.rating),reverse=True) now = datetime.now() s = filter(lambda p: now - p.lastUpdate < timedelta(days=60), s) rank = 1 @@ -76,7 +74,6 @@ def updatePlayerRanks(force=False): player_ranks.update({p:rank}) rank += 1 - ############################################################# ################## Write/Load External DB ################### ############################################################# @@ -94,6 +91,23 @@ def save_psql(): ###################### Python API ########################### ############################################################# +def getBalanceForPlayers(players, buddies=None): + if not players: + return "" + StorrageBackend.sync_from_database(players) + for p in players: + print(p, p.rating) + arr = sorted(players, key=lambda x: x.rating.mu, reverse=True) + ret="" + i = 0 + while i < len(arr): + ret += "{}|{},".format(players[i].name,(i%2)+2) + i += 1 + return ret + +def getPlayer(pid, name="NOTFOUND"): + return known_player[pid] + def fuzzy_find_player(name): ret = "" tup_list = [] @@ -114,32 +128,29 @@ def get_player_rank(p): except KeyError: return "N/A" - -def dumpRatings(top=0, forceMeanSort=False, enforceWhitelist=None): - global known_players - ret = "" - updatePlayerRanks(force=True) +def quality(team1, team2, names1 = [""], names2 = [""]): + mu1 = sum(r.mu for r in team1) + mu2 = sum(r.mu for r in team2) + mu_tot = mu1 + mu2 + sig1 = sum(r.sigma for r in team1) + sig2 = sum(r.sigma for r in team2) + sigtot = sig1 + sig2 - if forceMeanSort: - sort = sorted(known_players.values(), \ - key=lambda x: x.rating.mu,reverse=True) - else: - sort = sorted(known_players.values(), \ - key=lambda x: TS.get_env().expose(x.rating),reverse=True) - if enforceWhitelist: - sort = list(filter(lambda x: x.name in enforceWhitelist, sort)) + names1 = list(map(lambda x: str(x.name), names1)) + names2 = list(map(lambda x: str(x.name), names2)) - tmp = ["{} {} mean: {} var: {} WinRatio: {}% ({} Games)".format( \ - x.get_name().ljust(30), \ - str(int(TS.get_env().expose(x.rating))).rjust(5), \ - str(int(x.rating.mu)).rjust(4), \ - str(int(x.rating.sigma)).rjust(4),x.winratio().rjust(4), \ - str(x.games).rjust(3)) \ - for x in sort] - if top != 0: - tmp = tmp[:top] - count = 0 - for s in tmp: - count += 1 - ret += ("Rank: "+str(count).rjust(4) +" " + s + "\n") - return ret + diff = abs(mu1 - mu2) + percent = 50 + diff/mu_tot*100 + if percent > 100: + percent = 100 + + if mu1 > mu2: + string = "{} win at {:.2f}% - {:.2f} to {:.2f} Uncertainty: {:.2f}%".format(\ + ",".join(names1), \ + percent, mu1, mu2, sigtot/diff*100) + else: + string = "{} win at {:.2f}% - {:.2f} to {:.2f} Uncertainty: {:.2f}%".format(\ + ",".join(names2), \ + percent, mu2, mu1, sigtot/diff*100) + + return string diff --git a/TrueSkillWrapper.py b/TrueSkillWrapper.py index 69ac287..eaed010 100644 --- a/TrueSkillWrapper.py +++ b/TrueSkillWrapper.py @@ -10,6 +10,10 @@ updateLock = threading.RLock() dirty_rounds = 0 clean_rounds = 0 +##################################################### +################ HANDLE RATING INPUT ################ +##################################################### + def evaluate_round(r): global clean_rounds global dirty_rounds @@ -31,47 +35,50 @@ def evaluate_round(r): updateLock.release() -def rate_teams_simple(winner_team,loser_team,weights): +def rate_teams_simple(winner_team, loser_team, weights=None): global clean_rounds - groups = [winner_team]+[loser_team] + groups = [winner_team] + [loser_team] if len(groups[1]) == 0 or len(groups[0]) ==0 : print("WARNING: Groups were {} - {} INCOMPLETE, SKIP".format(len(groups[0]),len(groups[1]))) return False + rated = env.rate(groups,weights=weights) StorrageBackend.sync_to_database(rated[0],True) StorrageBackend.sync_to_database(rated[1],False) clean_rounds += 1 return True -def quality(team1,team2, names1 = [""], names2 = [""]): - mu1 = sum(r.mu for r in team1) - mu2 = sum(r.mu for r in team2) - mu_tot = mu1 + mu2 - sig1 = sum(r.sigma for r in team1) - sig2 = sum(r.sigma for r in team2) - sigtot = sig1 + sig2 +##################################################### +################### LOCK/GETTER #################### +##################################################### - names1 = list(map(lambda x: str(x.name), names1)) - names2 = list(map(lambda x: str(x.name), names2)) +def lock(): + updateLock.acquire() - diff = abs(mu1 - mu2) - percent = 50 + diff/mu_tot*100 - if percent > 100: - percent = 100 +def unlock(): + updateLock.release() - if mu1 > mu2: - string = "{} win at {:.2f}% - {:.2f} to {:.2f} Uncertainty: {:.2f}%".format(\ - ",".join(names1), \ - percent, mu1, mu2, sigtot/diff*100) - else: - string = "{} win at {:.2f}% - {:.2f} to {:.2f} Uncertainty: {:.2f}%".format(\ - ",".join(names2), \ - percent, mu2, mu1, sigtot/diff*100) - - return string +def newRating(mu=None): + if mu: + return Rating(mu=mu, sigma=env.sigma) + return env.create_rating() -def player_debug(sid,rated,groups): +def getEnviroment(): + return env + + +def balance(players, buddies=None): + raise NotImplementedError() + +def get_player_rating(sid, name="NOTFOUND"): + raise NotImplementedError() + +##################################################### +############### DEBUGGING FUNCTIONS ################# +##################################################### + +def playerDebug(sid,rated,groups): print("winner") for key in groups[0]: @@ -98,41 +105,3 @@ def player_debug(sid,rated,groups): print("Before: {}".format(groups[1][p])) print("After: {}".format(rated[1][p])) print("\n") - - -def balance(players, buddies=None): - if not players: - return "" - StorrageBackend.sync_from_database(players) - for p in players: - print(p, p.rating) - arr = sorted(players, key=lambda x: x.rating.mu, reverse=True) - ret="" - i = 0 - while i < len(arr): - ret += "{}|{},".format(players[i].name,(i%2)+2) - i += 1 - return ret - -def get_player_rating(sid, name="NOTFOUND"): - try: - p = StorrageBackend.known_players[sid] - tmp = int(env.expose(p.rating)) - return "Rating of '{}' : {} (Rank: {})".format(p.name, tmp, StorrageBackend.get_player_rank(p)) - except KeyError: - return "Rating of '{}' : No Rating (yet).".format(name) - -def lock(): - updateLock.acquire() - -def unlock(): - updateLock.release() - -def new_rating(mu=None): - if mu: - return Rating(mu=mu, sigma=env.sigma) - return env.create_rating() - -def get_env(): - return env -