public void GetZScore_Delta100_0Dot64() { var act = Elo.GetZScore(1600, 1500); var exp = 0.64; Assert.AreEqual(exp, act, 0.001); }
public void Calculate(Vote vote, double k) { lookup.TryGetValue(vote.Left, out Rank l); lookup.TryGetValue(vote.Right, out Rank r); if (l == null) { if (r != null) { r.Rating += vote.Score > 0.5 ? -k : k / 10; } return; } if (r == null) { l.Rating += vote.Score < 0.5 ? -k : k / 10; return; } var z = Elo.GetZScore(l.Rating, r.Rating); l.Rating += k * vote.Total * (vote.Score - z); r.Rating += k * vote.Total * (z - vote.Score); }
public void Process(ConcurrentQueue <BattlePairing> results) { var ids = new List <int>(); lock (locker) { BattlePairing pairing; while (results.TryDequeue(out pairing)) { var bot0 = pairing.Bot0; var bot1 = pairing.Bot1; var result = pairing.Result; bot0.Stats.Update(result); bot1.Stats.Update(result.Mirror()); var elo0 = bot0.Elo; var elo1 = bot1.Elo; var z0 = Elo.GetZScore(elo0, elo1); var z1 = Elo.GetZScore(elo1, elo0); switch (result.Outcome) { case BattleSimulation.Outcome.Win: elo0 = bot0.Elo + (1.0 - z0) * bot0.K; elo1 = bot1.Elo + (0.0 - z1) * bot1.K; break; case BattleSimulation.Outcome.Draw: elo0 = bot0.Elo + (0.5 - z0) * bot0.K; elo1 = bot1.Elo + (0.5 - z1) * bot1.K; break; case BattleSimulation.Outcome.Loss: elo0 = bot0.Elo + (0.0 - z0) * bot0.K; elo1 = bot1.Elo + (1.0 - z1) * bot1.K; break; } bot0.Elo = elo0; bot1.Elo = elo1; if (bot0.IsStable || bot1.IsStable) { bot0.UpdateK(); bot1.UpdateK(); } } var avg = AverageElo; var dif = avg - AppConfig.Data.EloInitial; foreach (var bot in Values) { bot.Elo -= dif; } // Add elo's that are to low too. ids = ByElo() .Skip(2) .Where(item => !item.Locked && item.Elo < Bottom) .Select(item => item.Id) .ToList(); } foreach (var id in ids) { BotData bot; TryRemove(id, out bot); } }