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;
        }
示例#3
0
        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;
        }