public void Calculate1v1Elo() { if (!HasBots) { var losers = SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).ToList(); var winners = SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).ToList(); if (losers.Count == 1 && winners.Count == 1) { SpringBattlePlayer winner = winners.First(); SpringBattlePlayer loser = losers.First(); Account winnerAcc = winner.Account; Account loserAcc = loser.Account; var winnerElo = winnerAcc.Elo1v1; var loserElo = loserAcc.Elo1v1; var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); var scoreWin = 32 * (1 - eWin); var scoreLose = 32 * (0 - eLose); winnerAcc.Elo1v1 += scoreWin; loserAcc.Elo1v1 += scoreLose; winner.EloChange = (float)scoreWin; loser.EloChange = (float)scoreLose; winnerAcc.XP += WinnerTeamXpChange.Value; loserAcc.XP += LoserTeamXpChange.Value; var sumW = winnerAcc.Elo1v1Weight + loserAcc.Elo1v1Weight; winnerAcc.Elo1v1Weight = Account.AdjustEloWeight(winnerAcc.Elo1v1Weight, sumW, 2); winnerAcc.EloWeight = Account.AdjustEloWeight(winnerAcc.EloWeight, sumW, 2); loserAcc.Elo1v1Weight = Account.AdjustEloWeight(loserAcc.Elo1v1Weight, sumW, 2); loserAcc.EloWeight = Account.AdjustEloWeight(loserAcc.EloWeight, sumW, 2); } } }
public void CalculateAllElo(bool noElo = false, bool planetwars = false) { if (IsEloProcessed || Duration < GlobalConst.MinDurationForElo) { IsEloProcessed = true; return; } if (IsMission || HasBots || PlayerCount < 2) { WinnerTeamXpChange = GlobalConst.XpForMissionOrBotsVictory; LoserTeamXpChange = GlobalConst.XpForMissionOrBots; if (Duration < GlobalConst.MinDurationForXP) { WinnerTeamXpChange = 0; LoserTeamXpChange = 0; } foreach (var a in SpringBattlePlayers.Where(x => !x.IsSpectator)) { if (a.IsInVictoryTeam) { a.Account.XP += WinnerTeamXpChange.Value; a.XpChange = WinnerTeamXpChange.Value; } else { a.Account.XP += LoserTeamXpChange.Value; a.XpChange = LoserTeamXpChange.Value; } } IsEloProcessed = true; return; } double winnerW = 0; double loserW = 0; double winnerInvW = 0; double loserInvW = 0; double winnerElo = 0; double loserElo = 0; var losers = SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); var winners = SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); if (losers.Count == 0 || winners.Count == 0) { IsEloProcessed = true; return; } foreach (var r in winners) { winnerW += r.Account.EloWeight; winnerInvW += r.Account.EloInvWeight; winnerElo += r.Account.EffectiveElo; } foreach (var r in losers) { loserW += r.Account.EloWeight; loserInvW += r.Account.EloInvWeight; loserElo += r.Account.EffectiveElo; } winnerElo = winnerElo / winners.Count; loserElo = loserElo / losers.Count; //winnerElo = winnerElo/winnerW; //loserElo = loserElo/loserW; var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); var sumCount = losers.Count + winners.Count; var scoreWin = Math.Sqrt(sumCount / 2.0) * 32 * (1 - eWin) / winnerInvW; var scoreLose = Math.Sqrt(sumCount / 2.0) * 32 * (0 - eLose) / loserInvW; var sumW = winnerW + loserW; if (Duration >= GlobalConst.MinDurationForXP) { WinnerTeamXpChange = (int)(20 + (300 + 600 * (1 - eWin)) / (3.0 + winners.Count)); LoserTeamXpChange = (int)(20 + (200 + 400 * (1 - eLose)) / (2.0 + losers.Count)); } else { WinnerTeamXpChange = 0; LoserTeamXpChange = 0; } if (noElo || ResourceByMapResourceID.MapIsSpecial == true) // silly map, just process XP { foreach (var r in winners) { r.Account.XP += WinnerTeamXpChange.Value; r.Player.XpChange = WinnerTeamXpChange; } foreach (var r in losers) { r.Account.XP += LoserTeamXpChange.Value; r.Player.XpChange = LoserTeamXpChange.Value; } IsEloProcessed = true; return; } if (losers.Count == 1 && winners.Count == 1) { Calculate1v1Elo(); } else { foreach (var r in winners) { var change = (float)(scoreWin * r.Account.EloInvWeight); r.Player.EloChange = change; if (planetwars) { r.Account.EloPw += change; } else { r.Account.Elo += change; } r.Account.XP += WinnerTeamXpChange.Value; r.Player.XpChange = WinnerTeamXpChange; r.Account.EloWeight = Account.AdjustEloWeight(r.Account.EloWeight, sumW, sumCount); r.Account.Elo1v1Weight = Account.AdjustEloWeight(r.Account.Elo1v1Weight, sumW, sumCount); } foreach (var r in losers) { var change = (float)(scoreLose * r.Account.EloInvWeight); r.Player.EloChange = change; if (planetwars) { r.Account.EloPw += change; } else { r.Account.Elo += change; } r.Account.XP += LoserTeamXpChange.Value; r.Player.XpChange = LoserTeamXpChange.Value; r.Account.EloWeight = Account.AdjustEloWeight(r.Account.EloWeight, sumW, sumCount); r.Account.Elo1v1Weight = Account.AdjustEloWeight(r.Account.Elo1v1Weight, sumW, sumCount); } } IsEloProcessed = true; }
private void CalculateEloGeneric(Func <Account, double> getElo, Func <Account, double> getWeight, Action <Account, double> setElo, Action <Account, double> setWeight) { double winnerW = 0; double loserW = 0; double winnerInvW = 0; double loserInvW = 0; double winnerElo = 0; double loserElo = 0; var losers = SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); var winners = SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); if ((losers.Count == 0) || (winners.Count == 0)) { IsEloProcessed = true; return; } foreach (var r in winners) { winnerW += getWeight(r.Account); winnerInvW += GlobalConst.EloWeightMax + 1 - getWeight(r.Account); winnerElo += getElo(r.Account); } foreach (var r in losers) { loserW += getWeight(r.Account); loserInvW += GlobalConst.EloWeightMax + 1 - getWeight(r.Account); loserElo += getElo(r.Account); } winnerElo = winnerElo / winners.Count; loserElo = loserElo / losers.Count; //winnerElo = winnerElo/winnerW; //loserElo = loserElo/loserW; var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); var sumCount = losers.Count + winners.Count; var scoreWin = Math.Sqrt(sumCount / 2.0) * 32 * (1 - eWin) / winnerInvW; var scoreLose = Math.Sqrt(sumCount / 2.0) * 32 * (0 - eLose) / loserInvW; WinnerTeamXpChange = (int)(20 + (300 + 600 * (1 - eWin)) / (3.0 + winners.Count)); // a bit ugly this sets to battle directly LoserTeamXpChange = (int)(20 + (200 + 400 * (1 - eLose)) / (2.0 + losers.Count)); var sumW = winnerW + loserW; foreach (var r in winners) { var change = (float)(scoreWin * (GlobalConst.EloWeightMax + 1 - getWeight(r.Account))); r.Player.EloChange = change; setElo(r.Account, getElo(r.Account) + change); setWeight(r.Account, Account.AdjustEloWeight(getWeight(r.Account), sumW, sumCount)); } foreach (var r in losers) { var change = (float)(scoreLose * (GlobalConst.EloWeightMax + 1 - getWeight(r.Account))); r.Player.EloChange = change; setElo(r.Account, getElo(r.Account) + change); setWeight(r.Account, Account.AdjustEloWeight(getWeight(r.Account), sumW, sumCount)); } IsEloProcessed = true; }