public List <int> GetAllyteamIds() { var allPlayers = SpringBattlePlayers.Where(x => !x.IsSpectator).ToList(); var allBots = SpringBattleBots.ToList(); return(allPlayers.Select(x => x.AllyNumber).Union(allBots.Select(x => x.AllyNumber)).OrderBy(x => x).ToList()); }
public List <float> GetAllyteamWinChances() { if (!IsRatedMatch()) { return(new List <float>()); } return(RatingSystems.GetRatingSystem(GetRatingCategory()).PredictOutcome(SpringBattlePlayers.Where(x => !x.IsSpectator).OrderBy(x => x.AllyNumber).GroupBy(x => x.AllyNumber).Select(x => x.Select(y => y.Account).ToList()).ToList(), StartTime)); }
private void ApplyXpChanges() { foreach (var a in SpringBattlePlayers.Where(x => !x.IsSpectator)) { if (a.IsInVictoryTeam) { a.Account.Xp += WinnerTeamXpChange ?? 0; a.XpChange = WinnerTeamXpChange; } else { a.Account.Xp += LoserTeamXpChange ?? 0; a.XpChange = LoserTeamXpChange; } } }
public void CalculateAllElo(bool noElo = false) { if (IsEloProcessed) { return; } if (!noElo) { ResetApplicableRatings(); } if (IsRatedMatch()) { Rank = SpringBattlePlayers.Select(x => x.Account.Rank).Max(); } if (Duration > GlobalConst.MinDurationForXP) { if (!IsRatedMatch()) { WinnerTeamXpChange = GlobalConst.XpForMissionOrBotsVictory; LoserTeamXpChange = GlobalConst.XpForMissionOrBots; } else { var losers = SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => x.Account).ToList(); var winners = SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => x.Account).ToList(); if ((losers.Count > 0) && (winners.Count > 0)) { List <float> probabilities = RatingSystems.GetRatingSystem(GetRatingCategory()).PredictOutcome(new List <ICollection <Account> > { winners, losers }, StartTime); var eWin = probabilities[0]; var eLose = probabilities[1]; 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)); } } ApplyXpChanges(); } IsEloProcessed = true; }
public Dictionary <int, float> GetAllyteamWinChances() { var allyteams = SpringBattlePlayers.Where(x => !x.IsSpectator).OrderBy(x => x.AllyNumber).Select(x => x.AllyNumber).Distinct().ToList(); try { if (IsRatedMatch()) { var chances = RatingSystems.GetRatingSystem(GetRatingCategory()).PredictOutcome(SpringBattlePlayers.Where(x => !x.IsSpectator).OrderBy(x => x.AllyNumber).GroupBy(x => x.AllyNumber).Select(x => x.Select(y => y.Account).ToList()).ToList(), StartTime); return(allyteams.Zip(chances, (k, v) => new { k, v }).ToDictionary(x => x.k, x => x.v)); } } catch (Exception ex) { Trace.TraceWarning("Invalid rating settings for B" + SpringBattleID + ", unable to calculate win chances. \n" + ex); } return(allyteams.ToDictionary(x => x, x => 1f / allyteams.Count)); }
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 List <float> GetAllyteamWinChances() { try { if (IsRatedMatch()) { return(RatingSystems.GetRatingSystem(GetRatingCategory()).PredictOutcome(SpringBattlePlayers.Where(x => !x.IsSpectator).OrderBy(x => x.AllyNumber).GroupBy(x => x.AllyNumber).Select(x => x.Select(y => y.Account).ToList()).ToList(), StartTime)); } } catch (Exception ex) { Trace.TraceWarning("Invalid rating settings for B" + SpringBattleID + ", unable to calculate win chances. \n" + ex); } return(new List <float>(new float[GetAllyteamIds().Count])); }
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; }