import random import pandas as pd import os class Model: """ Class containing the info of a model. :param name: Name of the model :param elo: Elo rating of the model :param games_played: Number of games played by the model (useful if we implement sigma uncertainty) """ def __init__(self, name, elo): self.name = name self.elo = elo self.games_played = 0 class Matchmaking: """ Class managing the matchmaking between the models. :param models: List of models :param queue: Temporary list of models used for the matching process :param k: Dev coefficient :param max_diff: Maximum difference considered between two models' elo :param matches: Dictionary containing the match history (to later upload as CSV) """ def __init__(self): self.models = [] self.queue = [] self.start_elo = 1200 self.k = 20 self.max_diff = 500 self.matches = pd.DataFrame() def read_history(self): """ Read the match history from the CSV files, concat the Dataframes and sort them by datetime. """ path = "match_history" files = os.listdir(path) for file in files: self.matches = pd.concat([self.matches, pd.read_csv(os.path.join(path, file))], ignore_index=True) self.matches["datetime"] = pd.to_datetime(self.matches["datetime"], format="%Y-%m-%d %H:%M:%S.%f", errors="coerce") self.matches = self.matches.dropna() self.matches = self.matches.sort_values("datetime") self.matches.reset_index(drop=True, inplace=True) model_names = self.matches["model1"].unique() self.models = [Model(name, self.start_elo) for name in model_names] def compute_elo(self): """ Compute the elo for each model after each match. """ for i, row in self.matches.iterrows(): model1 = self.get_model(row["model1"]) model2 = self.get_model(row["model2"]) result = row["result"] delta = model1.elo - model2.elo win_probability = 1 / (1 + 10 ** (-delta / 500)) model1.elo += self.k * (result - win_probability) model2.elo -= self.k * (result - win_probability) model1.games_played += 1 model2.games_played += 1 def save_elo_data(self): """ Save the match history as a CSV file to the hub. """ df = pd.DataFrame(columns=['name', 'elo']) for model in self.models: df = pd.concat([df, pd.DataFrame([[model.name, model.elo]], columns=['name', 'elo'])]) df.to_csv('elo.csv', index=False) def get_model(self, name): """ Return the Model with the given name. """ for model in self.models: if model.name == name: return model return None