def run(games, ratings, use_default_rating=False): """Update ratings based on games, and return new ratings GAMES is a list of dict objects, containing the following keys: players: a list of player identifiers rank: a list of places in the game RATINGS is a dictionary of player identifiers matched with their (mu, sigma) rating. RATINGS is modified in this function. If USE_DEFAULT_RATING is False, an error is thrown if a player in games is not in RATINGS. Otherwise, the default mu and sigma are used. """ trueskill.SetParameters(gamma=0.0) for game in games: players = [] for k in xrange(len(game['players'])): p = Player() p.id = game['players'][k] p.rank = game['rank'][k] if ratings.has_key(p.id): p.skill = ratings[p.id] elif use_default_rating: p.skill = (trueskill.INITIAL_MU, trueskill.INITIAL_SIGMA) else: raise Exception("Rating missing for: %s" % p.id) players.append(p) trueskill.AdjustPlayers(players) for p in players: ratings[p.id] = p.skill
def calculate(p1,p2,winconstant): # The output of this program should match the output of the TrueSkill # calculator at: # # http://atom.research.microsoft.com/trueskill/rankcalculator.aspx # # (Select game mode "custom", create 2 players each on their own team, # check the second "Draw?" box to indicate a tie for second place, # then click "Recalculate Skill Level Distribution". The mu and sigma # values in the "after game" section should match what this program # prints. # The objects we pass to AdjustPlayers can be anything with skill and # rank attributes. We'll create a simple Player class that has # nothing else. class Player(object): pass # Create two players. Assign each of them the default skill. The # player ranking (their "level") is mu-3*sigma, so the default skill # value corresponds to a level of 0. #ermac = Player() #ermac.skill = (25.0, 25.0/3.0) # The two players play a game. Orc wins, Hurda is # lost. The actual numerical values of the # ranks don't matter, they could be (1, 2) or (1, 2) or # (23, 45). All that matters is that a smaller rank beats a # larger one, and equal ranks indicate draws. #ermac.rank = 2 # Do the computation to find each player's new skill estimate. trueskill.AdjustPlayers([p1, p2],winconstant) return (p1,p2) # Print the results. msg = " p1: mu={0[0]:.3f} sigma={0[1]:.3f} <br>".format(p1.skill) msg += " p2: mu={0[0]:.3f} sigma={0[1]:.3f}".format(p2.skill) return msg
def calc_ranks_py(self, players, ranks, db): class TrueSkillPlayer(object): def __init__(self, name, skill, rank): self.name = name self.old_skill = skill self.skill = skill self.rank = rank ts_players = [] for i, p in enumerate(players): pdata = db.get_player((p, )) ts_players.append( TrueSkillPlayer(i, (pdata[0][6], pdata[0][7]), ranks[i])) try: trueskill.AdjustPlayers(ts_players) except Exception, e: log.error("trueskill-py: " + e) return
def process_replay(replayidx, replay): global NrGames if "error" in replay: return False botidx = [getbotidx(name) for name in replay["playernames"]] for gameidx in range(len(botidx)): bot = Bots[botidx[gameidx]] bot.addgame(replayidx, gameidx, replay["status"][gameidx]) myscore = replay["score"][gameidx] myrank = replay["rank"][gameidx] for othergameidx in range(len(botidx)): otheridx = botidx[othergameidx] if botidx[gameidx] == otheridx: continue otherscore = replay["score"][othergameidx] otherrank = replay["rank"][othergameidx] if myscore > otherscore: assert myrank < otherrank bot.addmatch(otheridx, +1) elif myscore == otherscore: assert myrank == otherrank bot.addmatch(otheridx, 0) else: assert myrank > otherrank bot.addmatch(otheridx, -1) bots = [Bots[botidx[i]] for i in range(len(botidx))] for i in range(len(bots)): bots[i].rank = replay["rank"][i] trueskill.AdjustPlayers(bots) NrGames += 1 return True
# value corresponds to a level of 0. orc = Player() orc.skill = (25.0, 25.0 / 3.0) hurda = Player() hurda.skill = (25.0, 25.0 / 3.0) #ermac = Player() #ermac.skill = (25.0, 25.0/3.0) # The two players play a game. Orc wins, Hurda is # lost. The actual numerical values of the # ranks don't matter, they could be (1, 2) or (1, 2) or # (23, 45). All that matters is that a smaller rank beats a # larger one, and equal ranks indicate draws. orc.rank = 1 hurda.rank = 2 #ermac.rank = 2 # Do the computation to find each player's new skill estimate. trueskill.AdjustPlayers([orc, hurda]) # Print the results. print(" Orc: mu={0[0]:.3f} sigma={0[1]:.3f}".format(orc.skill)) print(" Hurda: mu={0[0]:.3f} sigma={0[1]:.3f}".format(hurda.skill)) #print(" Ermac: mu={0[0]:.3f} sigma={0[1]:.3f}".format(ermac.skill))
parser.add_option("-s", "--shelf") opts, args = parser.parse_args() player_index = defaultdict(Player) if opts.shelf: with closing(shelve.open(opts.shelf)) as p: player_index.update(p) if opts.input: with open(opts.input) as f: reader = csv.reader(f) for row in reader: winner = int(row[4]) p_objs = [] for i, p in enumerate(row[:4]): p_obj = player_index[p] p_obj.rank = 1 if i == winner else 2 p_objs.append(p_obj) trueskill.AdjustPlayers(p_objs) if opts.shelf: with closing(shelve.open(opts.shelf)) as p: p.update(player_index) for p in sorted(player_index, key=lambda l: player_index[l].skill, reverse=True): pl = player_index[p] print "{0}: mu={1[0]:.3f} sigma={1[1]:.3f}".format(p, pl.skill)
darren.skill = (25.0, 25.0/3.0) # The four players play a game. Alice wins, Bob and Chris tie for # second, Darren comes in last. The actual numerical values of the # ranks don't matter, they could be (1, 2, 2, 4) or (1, 2, 2, 3) or # (23, 45, 45, 67). All that matters is that a smaller rank beats a # larger one, and equal ranks indicate draws. alice.rank = 1 bob.rank = 2 chris.rank = 2 darren.rank = 4 # Do the computation to find each player's new skill estimate. trueskill.AdjustPlayers([alice, bob, chris, darren]) # Print the results. print(" Alice: mu={0[0]:.3f} sigma={0[1]:.3f}".format(alice.skill)) print(" Bob: mu={0[0]:.3f} sigma={0[1]:.3f}".format(bob.skill)) print(" Chris: mu={0[0]:.3f} sigma={0[1]:.3f}".format(chris.skill)) print("Darren: mu={0[0]:.3f} sigma={0[1]:.3f}".format(darren.skill)) ########NEW FILE######## __FILENAME__ = trueskill #!/usr/bin/python # Copyright 2010 Doug Zongker # # Licensed under the Apache License, Version 2.0 (the "License");
def main(): global MINGAMES trueskill.SetParameters(beta=25.0 / 3.0, draw_probability=0.3) with open(sys.argv[1], 'r') as filp: settings = json.load(filp) if "mingames" in settings: MINGAMES = settings["mingames"] maps = helpers.listmaps(settings["ants"] + "maps") gameid = getfirstgameid() staticbots = [StaticBot(cmd) for cmd in settings["static"]] tunegroups = [TuneGroup(group) for group in settings["tune"]] while True: seedbot = tunegroups[0].run() otherbots = staticbots + [ bot for group in tunegroups for bot in group.population if bot != seedbot ] maprec = random.choice(maps) print "Game {gameid}: {maprec[players]} player map {maprec[path]}".format( **locals()) mapbots = [seedbot] + random.sample(otherbots, maprec["players"] - 1) botcmds = [bot.getcmd() for bot in mapbots] for idx in range(len(botcmds)): cmd = botcmds[idx] skill = mapbots[idx].skill print " ", "({mu:3}, {sigma:3}):".format( mu=skill[0], sigma=skill[1]), cmd[cmd.rfind('/') + 1:] args = [ settings["ants"] + "playgame.py", "--turns", "1000", "--turntime", "500", "--log_dir", "tune_logs", "--nolaunch", "--serial", "-g", str(gameid), "--map", maprec["path"], ] + botcmds subprocess.check_call(args) with open('tune_logs/{0}.replay'.format(gameid), 'r') as filp: replay = json.load(filp) if "error" in replay: print "An error occurred" print replay["error"] return rank = replay["rank"] print " Ranks:", ', '.join([str(r) for r in rank]) for idx in range(len(rank)): mapbots[idx].rank = rank[idx] mapbots[idx].nrgames += 1 trueskill.AdjustPlayers(mapbots) print " ", ', '.join("{name} ({mu:3}, {sigma:3})".format( name=bot.getname(), mu=bot.skill[0], sigma=bot.skill[1]) for bot in mapbots) gameid += 1
#!/usr/bin/python import sys import trueskill import json class MyDict(dict): def __getattr__(self, name): return self[name] def __setattr__(self, name, value): self[name] = value data = json.loads(sys.argv[1]) data = [MyDict(j) for j in data] trueskill.AdjustPlayers(data) print json.dumps(data)
line_count = int(f.read()) with open(play_log) as f: history = islice(f, line_count, line_count+BATCH_SIZE) i = 0 for row in history: i += 1 m = RE_LOGLINE.match(row) if m: winner = m.group('winner') players= [] for p_name in ['player1','player2','player3','player4']: p_obj = player_index[m.group(p_name)] p_obj.rank = 1 if m.group(p_name) == winner else 2 players.append(p_obj) trueskill.AdjustPlayers(players) with open(P_LC,'w') as f: f.write(str(line_count+i)) with closing(shelve.open(P_ESTIM)) as p: p.update(player_index) body = '' body += '<p>Previously processed {0} games. Now processed {1} new games. We have {2} players.</p>'.format(line_count,i,len(player_index)) for p in sorted(player_index, key=lambda l:player_index[l].skill, reverse=True): pl = player_index[p] body += "<p>{0}: mu={1[0]:.3f} sigma={1[1]:.3f}</p>".format(p, pl.skill)