Exemplo n.º 1
0
 private void rdoBalanceCH_CheckedChanged(object sender, EventArgs e)
 {
     if (rdoBalanceCH.Checked)
     {
         CurrentBalanceMode = BalanceMode.OppositeClasses;
     }
 }
Exemplo n.º 2
0
 private void rdoBalanceBoth_CheckedChanged(object sender, EventArgs e)
 {
     if (rdoBalanceBoth.Checked)
     {
         CurrentBalanceMode = BalanceMode.Both;
     }
 }
Exemplo n.º 3
0
 private void rdoBalanceCC_CheckedChanged(object sender, EventArgs e)
 {
     if (rdoBalanceCC.Checked)
     {
         CurrentBalanceMode = BalanceMode.SameClasses;
     }
 }
        //Interface function to comply with LegacyBalance
        public static BalanceTeamsResult BalanceInterface(int teamCount, BalanceMode mode, LobbyHostingContext b, params List <Account>[] unmovablePlayers)
        {
            if (b.Players.Where(y => !y.IsSpectator).Count() > 38) // dont try doing million+ iterations (arbitrarily chosen cap)
            {
                Trace.TraceWarning("PartitionBalance called with too many players: " + b.Players.Where(y => !y.IsSpectator).Count());
                return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers));
            }
            if (teamCount != 2)
            {
                Trace.TraceWarning("PartitionBalance called with invalid number of teams: " + teamCount);
                return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers));
            }
            if (unmovablePlayers.Length > 0)
            {
                Trace.TraceWarning("PartitionBalance called with too many unmovable players: " + unmovablePlayers.Length);
                return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers));
            }
            if (mode == BalanceMode.FactionWise)
            {
                Trace.TraceWarning("PartitionBalance called with FactionWise balance mode, which is unsupported");
                return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers));
            }
            try
            {
                if (b.IsMatchMakerGame)
                {
                    mode = BalanceMode.Party;
                }

                BalanceTeamsResult ret = new BalanceTeamsResult();

                ret.CanStart = true;
                ret.Players  = b.Players.ToList();
                ret.Bots     = b.Bots.ToList();

                List <PlayerItem> players = new List <PlayerItem>();
                using (var db = new ZkDataContext())
                {
                    var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList();
                    var accs        = db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList();
                    if (accs.Count < 1)
                    {
                        ret.CanStart = false;
                        return(ret);
                    }
                    players = b.Players.Where(y => !y.IsSpectator).Select(x => new PlayerItem(x.LobbyID, accs.First(a => a.AccountID == x.LobbyID).GetRating(b.ApplicableRating).Elo, x.Clan, x.PartyID)).ToList();
                }

                var dualResult = Balance(mode, players);
                dualResult.Players.ForEach(r => ret.Players.Where(x => x.LobbyID == r.LobbyID).ForEach(x => x.AllyID = r.AllyID));
                ret.Message = dualResult.Message;
                return(ret);
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("PartitionBalance encountered an error: " + ex);
                return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers));
            }
        }
 /// <summary>
 /// Initializes a new instance of the OperatorParamsDto class.
 /// </summary>
 /// <param name="transactionOfflineMode">Possible values include:
 /// 'Allow', 'Forbid'</param>
 /// <param name="balanceMode">Possible values include: 'OnlineBalance',
 /// 'OfflineBalance'</param>
 public OperatorParamsDto(int operatorId, int currencyId, TransactionOfflineMode transactionOfflineMode, BalanceMode balanceMode, string operatorName = default(string), string languageCode = default(string), string timezoneId = default(string))
 {
     OperatorId             = operatorId;
     OperatorName           = operatorName;
     CurrencyId             = currencyId;
     LanguageCode           = languageCode;
     TimezoneId             = timezoneId;
     TransactionOfflineMode = transactionOfflineMode;
     BalanceMode            = balanceMode;
     CustomInit();
 }
Exemplo n.º 6
0
        internal static string ToSerializedValue(this BalanceMode value)
        {
            switch (value)
            {
            case BalanceMode.OnlineBalance:
                return("OnlineBalance");

            case BalanceMode.OfflineBalance:
                return("OfflineBalance");
            }
            return(null);
        }
Exemplo n.º 7
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="sysSettings">Reference to system settings.</param>
 /// <param name="relayMode">Relay mode.</param>
 /// <param name="smartHostBalanceMode">Specifies how smart hosts will balance.</param>
 /// <param name="smartHosts">Smart hosts.</param>
 /// <param name="idleTimeout">Session idle timeout seconds.</param>
 /// <param name="maxConnections">Maximum conncurent conncetions.</param>
 /// <param name="maxConnectionsPerIP">Maximum conncurent conncetions to one IP address.</param>
 /// <param name="relayInterval">Relay messages interval seconds.</param>
 /// <param name="relayRetryInterval">Relay retry messages interval seconds.</param>
 /// <param name="undeliveredWarning">Specifies after how many minutes delayed delivery message is sent.</param>
 /// <param name="undelivered">Specifies after how many hours undelivered notification message is sent.</param>
 /// <param name="storeUndelivered">Specifies if undelivered messages are stored to "Undelivered" folder in mail store.</param>
 /// <param name="bindings">Specifies SMTP listening info.</param>
 internal Relay_Settings(System_Settings sysSettings,Relay_Mode relayMode,BalanceMode smartHostBalanceMode,Relay_SmartHost[] smartHosts,int idleTimeout,int maxConnections,int maxConnectionsPerIP,int relayInterval,int relayRetryInterval,int undeliveredWarning,int undelivered,bool storeUndelivered,IPBindInfo[] bindings)
 {
     m_pSysSettings          = sysSettings;
     m_RelayMode             = relayMode;
     m_SmartHostsBalanceMode = smartHostBalanceMode;
     m_pSmartHosts           = smartHosts;
     m_IdleTimeout           = idleTimeout;
     m_MaxConnections        = maxConnections;
     m_MaxConnectionsPerIP   = maxConnectionsPerIP;
     m_RelayInterval         = relayInterval;
     m_RelayRetryInterval    = relayRetryInterval;
     m_SendUndelWaringAfter  = undeliveredWarning;
     m_SendUndeliveredAfter  = undelivered;
     m_StoreUndeliveredMsgs  = storeUndelivered;
     m_pBinds                = bindings;
 }
Exemplo n.º 8
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="sysSettings">Reference to system settings.</param>
 /// <param name="relayMode">Relay mode.</param>
 /// <param name="smartHostBalanceMode">Specifies how smart hosts will balance.</param>
 /// <param name="smartHosts">Smart hosts.</param>
 /// <param name="idleTimeout">Session idle timeout seconds.</param>
 /// <param name="maxConnections">Maximum conncurent conncetions.</param>
 /// <param name="maxConnectionsPerIP">Maximum conncurent conncetions to one IP address.</param>
 /// <param name="relayInterval">Relay messages interval seconds.</param>
 /// <param name="relayRetryInterval">Relay retry messages interval seconds.</param>
 /// <param name="undeliveredWarning">Specifies after how many minutes delayed delivery message is sent.</param>
 /// <param name="undelivered">Specifies after how many hours undelivered notification message is sent.</param>
 /// <param name="storeUndelivered">Specifies if undelivered messages are stored to "Undelivered" folder in mail store.</param>
 /// <param name="bindings">Specifies SMTP listening info.</param>
 internal Relay_Settings(System_Settings sysSettings, Relay_Mode relayMode, BalanceMode smartHostBalanceMode, Relay_SmartHost[] smartHosts, int idleTimeout, int maxConnections, int maxConnectionsPerIP, int relayInterval, int relayRetryInterval, int undeliveredWarning, int undelivered, bool storeUndelivered, IPBindInfo[] bindings)
 {
     m_pSysSettings          = sysSettings;
     m_RelayMode             = relayMode;
     m_SmartHostsBalanceMode = smartHostBalanceMode;
     m_pSmartHosts           = smartHosts;
     m_IdleTimeout           = idleTimeout;
     m_MaxConnections        = maxConnections;
     m_MaxConnectionsPerIP   = maxConnectionsPerIP;
     m_RelayInterval         = relayInterval;
     m_RelayRetryInterval    = relayRetryInterval;
     m_SendUndelWaringAfter  = undeliveredWarning;
     m_SendUndeliveredAfter  = undelivered;
     m_StoreUndeliveredMsgs  = storeUndelivered;
     m_pBinds = bindings;
 }
Exemplo n.º 9
0
        BalanceTeamsResult LegacyBalance(int teamCount, BalanceMode mode, BattleContext b, params List <Account>[] unmovablePlayers)
        {
            var ret = new BalanceTeamsResult();

            try {
                ret.CanStart = true;
                ret.Players  = b.Players.ToList();

                var db          = new ZkDataContext();
                var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList();
                var accs        =
                    db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList();
                if (accs.Count < 1)
                {
                    ret.CanStart = false;
                    return(ret);
                }
                if (teamCount < 1)
                {
                    teamCount = 1;
                }
                if (teamCount > accs.Count)
                {
                    teamCount = accs.Count;
                }
                if (teamCount == 1)
                {
                    foreach (var p in ret.Players)
                    {
                        p.AllyID = 0;
                    }
                    return(ret);
                }

                maxTeamSize = (int)Math.Ceiling(accs.Count / (double)teamCount);

                teams.Clear();
                for (var i = 0; i < teamCount; i++)
                {
                    var team = new BalanceTeam();
                    teams.Add(team);
                    if (unmovablePlayers != null && unmovablePlayers.Length > i)
                    {
                        var unmovables = unmovablePlayers[i];
                        team.AddItem(new BalanceItem(unmovablePlayers[i].ToArray())
                        {
                            CanBeMoved = false
                        });
                        accs.RemoveAll(x => unmovables.Any(y => y.AccountID == x.AccountID));
                    }
                }

                balanceItems = new List <BalanceItem>();
                if (mode == BalanceMode.ClanWise)
                {
                    var clanGroups = accs.GroupBy(x => x.ClanID ?? x.AccountID).ToList();
                    if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize))
                    {
                        mode = BalanceMode.Normal;
                    }
                    else
                    {
                        balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(x.ToArray())));
                    }
                }
                if (mode == BalanceMode.FactionWise)
                {
                    balanceItems.Clear();
                    var factionGroups = accs.GroupBy(x => x.FactionID ?? x.AccountID).ToList();
                    balanceItems.AddRange(factionGroups.Select(x => new BalanceItem(x.ToArray())));
                }

                if (mode == BalanceMode.Normal)
                {
                    balanceItems.Clear();
                    balanceItems.AddRange(accs.Select(x => new BalanceItem(x)));
                }

                var sw = new Stopwatch();
                sw.Start();
                RecursiveBalance(0);
                sw.Stop();

                if (bestTeams == null)
                {
                    var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                    fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                    return(fallback);
                }

                var minSize    = bestTeams.Min(x => x.Count);
                var maxSize    = bestTeams.Max(x => x.Count);
                var sizesWrong = maxSize / (double)minSize > MaxTeamSizeDifferenceRatio;

                // cbalance failed, rebalance using normal
                if (mode == BalanceMode.ClanWise && (bestTeams == null || GetTeamsDifference(bestTeams) > MaxCbalanceDifference || sizesWrong))
                {
                    return(new Balancer().LegacyBalance(teamCount, BalanceMode.Normal, b, unmovablePlayers));
                }
                // cbalance failed, rebalance using normal

                if (sizesWrong && mode == BalanceMode.FactionWise)
                {
                    var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                    fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                    return(fallback); // fallback standard balance if PW balance fails

                    /*ret.CanStart = false;
                     * ret.Message = string.Format("Failed to balance - too many people from same faction");
                     * return ret;*/
                }

                if (unmovablePlayers != null && unmovablePlayers.Length > 0)
                {
                    var minElo = bestTeams.Min(x => x.AvgElo);
                    var maxElo = bestTeams.Max(x => x.AvgElo);
                    if (maxElo - minElo > GlobalConst.MaxPwEloDifference)
                    {
                        var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                        fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                        return(fallback); // fallback standard balance if PW balance fails

                        /*
                         * ret.CanStart = false;
                         * ret.Message = string.Format("Team difference is too big - win chance {0}% - spectate some or wait for more people",
                         *                          Utils.GetWinChancePercent(maxElo - minElo));
                         * return ret;*/
                    }
                }

                if (bestTeams == null)
                {
                    ret.CanStart = false;
                    ret.Message  =
                        string.Format(
                            "Failed to balance {0} - too many people from same clan or faction (in teams game you can try !random and !forcestart)");
                    return(ret);
                }
                else
                {
                    if (unmovablePlayers == null || unmovablePlayers.Length == 0)
                    {
                        bestTeams = bestTeams.Shuffle();                                                           // permute when not unmovable players present
                    }
                    var text = "( ";

                    var lastTeamElo = 0.0;
                    var allyNum     = 0;
                    foreach (var team in bestTeams)
                    {
                        if (allyNum > 0)
                        {
                            text += " : ";
                        }
                        text += string.Format("{0}", (allyNum + 1));
                        if (allyNum > 0)
                        {
                            text += string.Format("={0}%)", Utils.GetWinChancePercent(lastTeamElo - team.AvgElo));
                        }
                        lastTeamElo = team.AvgElo;

                        foreach (var u in team.Items.SelectMany(x => x.LobbyId))
                        {
                            ret.Players.Single(x => x.LobbyID == u).AllyID = allyNum;
                        }
                        allyNum++;
                    }
                    text += ")";

                    ret.Message = String.Format("{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time",
                                                bestTeams.Sum(x => x.Count),
                                                teamCount,
                                                mode,
                                                text,
                                                iterationsChecked,
                                                sw.ElapsedMilliseconds);
                }
            } catch (Exception ex) {
                Trace.TraceError(ex.ToString());
                ret.Message  = ex.ToString();
                ret.CanStart = false;
            }
            return(ret);
        }
Exemplo n.º 10
0
        //Balances N players in O(2^(n/2))
        //Algorithm described in http://web.cecs.pdx.edu/~bart/cs510ai/papers/korf-ckk.pdf Section 2.2
        public static DualBalanceResult Balance(BalanceMode mode, ICollection <PlayerItem> players)
        {
            List <PlayerItem>  unmodifiedPlayers = players.ToList();
            List <List <int> > playerGroups      = new List <List <int> >();
            List <double>      groupSkill        = new List <double>();

            players.ForEach(x => x.Elo += 1e6); //Purple for everyone, this assures that both teams get an equal number of players
            if (players.Count % 2 != 0)
            {
                //Pad teams to an even number
                players.Add(new PlayerItem(-1, players.Average(x => x.Elo), null, null));
            }
            int maxTeamSize = players.Count / 2;

            if (mode == BalanceMode.Party)
            {
                var partyGroups = players.GroupBy(x => x.Party ?? x.Account).ToList();
                if (2 > partyGroups.Count() || partyGroups.Any(x => x.Count() > maxTeamSize))
                {
                    //Party too big, fall through
                    mode = BalanceMode.Normal;
                }
                else
                {
                    playerGroups = partyGroups.Select(x => x.Select(p => p.Account).ToList()).ToList();
                    groupSkill   = partyGroups.Select(x => x.Sum(g => g.Elo)).ToList();
                }
            }

            if (mode == BalanceMode.ClanWise)
            {
                var clanGroups = players.GroupBy(x => x.Party ?? x.Clan ?? x.Account).ToList();
                if (2 > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize))
                {
                    //Clan or party too big, fall through
                    mode = BalanceMode.Normal;
                }
                else
                {
                    playerGroups = clanGroups.Select(x => x.Select(p => p.Account).ToList()).ToList();
                    groupSkill   = clanGroups.Select(x => x.Sum(g => g.Elo)).ToList();
                }
            }

            if (mode == BalanceMode.Normal)
            {
                playerGroups = players.Select(x => new List <int>()
                {
                    x.Account
                }).ToList();
                groupSkill = players.Select(x => x.Elo).ToList();
            }

            //Find optimal partitioning
            var sw = new Stopwatch();

            sw.Start();

            double sum = groupSkill.Sum();

            maxTeamSize = playerGroups.Count / 2;
            List <Subset> firstList  = generateAllSubsets(groupSkill.Where((x, i) => i < maxTeamSize).ToList());
            List <Subset> secondList = generateAllSubsets(groupSkill.Where((x, i) => i >= maxTeamSize).ToList());

            //Any partition can be represented as a combination of a partition of the first and the second half
            //There are N^2 possibilities, but we only look at the N ones where the sum of both is as close to the target as possible

            firstList.Sort();
            secondList.Sort();

            int    a              = 0;                    //Iterates first list in ascending order
            int    b              = secondList.Count - 1; //Iterates second list in descending order
            double bestDiff       = Double.MaxValue;
            UInt64 bestAssignment = 0;                    //Each bit from right to left represents whether the ith player is in the first or second team

            while (a < firstList.Count && b >= 0)
            {
                while (b >= 0 && firstList[a].Sum + secondList[b].Sum > sum / 2)
                {
                    b--;
                }
                if (b >= 0 && sum - 2 * (firstList[a].Sum + secondList[b].Sum) < bestDiff)
                {
                    bestDiff       = sum - 2 * (firstList[a].Sum + secondList[b].Sum);
                    bestAssignment = firstList[a].Elements | (secondList[b].Elements << (maxTeamSize));
                }
                a++;
            }

            sw.Stop();

            //Return results

            if (mode == BalanceMode.ClanWise && (bestDiff > MaxCbalanceDifference))
            {
                //Not very balanced, fall back
                return(Balance(BalanceMode.Normal, unmodifiedPlayers));
            }

            DualBalanceResult ret = new DualBalanceResult()
            {
                EloDifference = 2 * bestDiff / players.Count,
                Players       = players.Where(p => p.Account > 0).Select(x => new PlayerTeam()
                {
                    LobbyID = x.Account
                }).ToList()
            };

            int j = 0;

            while (j < playerGroups.Count)
            {
                //iterate through assignment bit by bit
                if ((bestAssignment & 0x1) == 0)
                {
                    ret.Players.Where(p => playerGroups[j].Contains(p.LobbyID)).ForEach(x => x.AllyID = 0);
                }
                else
                {
                    ret.Players.Where(p => playerGroups[j].Contains(p.LobbyID)).ForEach(x => x.AllyID = 1);
                }
                j++;
                bestAssignment >>= 1;
            }


            //Make that nice message

            var text = string.Format("( ( 1={0}%) : 2={1}%))", (int)Math.Round((1.0 / (1.0 + Math.Pow(10, -ret.EloDifference / 400.0))) * 100.0), (int)Math.Round((1.0 / (1.0 + Math.Pow(10, ret.EloDifference / 400.0))) * 100.0));

            ret.LowestWinChance = 1.0 / (1.0 + Math.Pow(10, ret.EloDifference / 400.0));

            ret.Message = string.Format(
                "{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time",
                unmodifiedPlayers.Count,
                2,
                mode,
                text,
                (1UL << maxTeamSize),
                sw.ElapsedMilliseconds);

            return(ret);
        }
Exemplo n.º 11
0
        /// <summary>
        ///     The function that actually moves players arounds
        /// </summary>
        /// <param name="teamCount"></param>
        /// <param name="mode"></param>
        /// <param name="b"></param>
        /// <param name="unmovablePlayers"></param>
        /// <returns></returns>
        BalanceTeamsResult LegacyBalance(int teamCount, BalanceMode mode, LobbyHostingContext b, params List<Account>[] unmovablePlayers)
        {
            var ret = new BalanceTeamsResult();

            if (b.IsMatchMakerGame) mode = BalanceMode.Party; // override, for matchmaker mode is always party
            
            try
            {
                ret.CanStart = true;
                ret.Players = b.Players.ToList();

                var db = new ZkDataContext();
                var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList();
                var accs = db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList();
                if (accs.Count < 1)
                {
                    ret.CanStart = false;
                    return ret;
                }
                if (teamCount < 1) teamCount = 1;
                if (teamCount > accs.Count) teamCount = accs.Count;
                if (teamCount == 1)
                {
                    foreach (var p in ret.Players) p.AllyID = 0;
                    return ret;
                }

                maxTeamSize = (int)Math.Ceiling(accs.Count / (double)teamCount);

                teams.Clear();
                for (var i = 0; i < teamCount; i++)
                {
                    var team = new BalanceTeam();
                    teams.Add(team);
                    if (unmovablePlayers != null && unmovablePlayers.Length > i)
                    {
                        var unmovables = unmovablePlayers[i];
                        team.AddItem(new BalanceItem(b.IsMatchMakerGame, unmovablePlayers[i].ToArray()) { CanBeMoved = false });
                        accs.RemoveAll(x => unmovables.Any(y => y.AccountID == x.AccountID));
                    }
                }

                balanceItems = new List<BalanceItem>();
                if (mode == BalanceMode.Party)
                {
                    var clanGroups = accs.GroupBy(x => b.Players.First(p => p.Name == x.Name).PartyID ?? x.AccountID).ToList();
                    if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) mode = BalanceMode.Normal;
                    else balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray())));
                }

                if (mode == BalanceMode.ClanWise)
                {
                    var clanGroups = accs.GroupBy(x => b.Players.First(p => p.Name == x.Name).PartyID ?? x.ClanID ?? x.AccountID).ToList();
                    if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) mode = BalanceMode.Normal;
                    else balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray())));
                }
                if (mode == BalanceMode.FactionWise)
                {
                    balanceItems.Clear();
                    var factionGroups = accs.GroupBy(x => x.FactionID ?? x.AccountID).ToList();
                    balanceItems.AddRange(factionGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray())));
                }

                if (mode == BalanceMode.Normal)
                {
                    balanceItems.Clear();
                    balanceItems.AddRange(accs.Select(x => new BalanceItem(b.IsMatchMakerGame, x)));
                }

                var sw = new Stopwatch();
                sw.Start();
                RecursiveBalance(0);
                sw.Stop();

                if (bestTeams == null)
                {
                    var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                    fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                    return fallback;
                }

                var minSize = bestTeams.Min(x => x.Count);
                var maxSize = bestTeams.Max(x => x.Count);
                var sizesWrong = maxSize / (double)minSize > MaxTeamSizeDifferenceRatio;

                // cbalance failed, rebalance using normal
                if (mode == BalanceMode.ClanWise && (bestTeams == null || GetTeamsDifference(bestTeams) > MaxCbalanceDifference || sizesWrong)) return new Balancer().LegacyBalance(teamCount, BalanceMode.Normal, b, unmovablePlayers);
                // cbalance failed, rebalance using normal

                if (sizesWrong && mode == BalanceMode.FactionWise)
                {
                    var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                    fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                    return fallback; // fallback standard balance if PW balance fails
                    /*ret.CanStart = false;
                    ret.Message = string.Format("Failed to balance - too many people from same faction");
                    return ret;*/
                }

                if (unmovablePlayers != null && unmovablePlayers.Length > 0)
                {
                    var minElo = bestTeams.Min(x => x.AvgElo);
                    var maxElo = bestTeams.Max(x => x.AvgElo);
                    if (maxElo - minElo > GlobalConst.MaxPwEloDifference)
                    {
                        var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null);
                        fallback.Message +=
                            "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction";
                        return fallback; // fallback standard balance if PW balance fails
                        /*
                        ret.CanStart = false;
                        ret.Message = string.Format("Team difference is too big - win chance {0}% - spectate some or wait for more people",
                                                    Utils.GetWinChancePercent(maxElo - minElo));
                        return ret;*/
                    }
                }

                if (bestTeams == null)
                {
                    ret.CanStart = false;
                    ret.Message =
                        string.Format(
                            "Failed to balance {0} - too many people from same clan or faction (in teams game you can try !random and !forcestart)");
                    return ret;
                }
                if (unmovablePlayers == null || unmovablePlayers.Length == 0) bestTeams = bestTeams.Shuffle(); // permute when not unmovable players present

                var text = "( ";

                var lastTeamElo = 0.0;
                var allyNum = 0;
                foreach (var team in bestTeams)
                {
                    if (allyNum > 0) text += " : ";
                    text += string.Format("{0}", (allyNum + 1));
                    if (allyNum > 0) text += string.Format("={0}%)", Utils.GetWinChancePercent(lastTeamElo - team.AvgElo));
                    lastTeamElo = team.AvgElo;

                    foreach (var u in team.Items.SelectMany(x => x.LobbyId)) ret.Players.Single(x => x.LobbyID == u).AllyID = allyNum;
                    allyNum++;
                }
                text += ")";

                ret.Message = string.Format(
                    "{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time",
                    bestTeams.Sum(x => x.Count),
                    teamCount,
                    mode,
                    text,
                    iterationsChecked,
                    sw.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                ret.Message = ex.ToString();
                ret.CanStart = false;
            }
            return ret;
        }
Exemplo n.º 12
0
        //public static bool UpdateBalance(CrmDbContext db, BankAccount account, double amount, BalanceMode balanceMode = BalanceMode.Increment)
        //{
        //    try
        //    {
        //        switch (balanceMode)
        //        {
        //            case BalanceMode.Increment:
        //                account.Balance += amount;
        //                break;
        //            case BalanceMode.Decrement:
        //                account.Balance -= amount;
        //                break;
        //        }
        //        db.Entry(account).State = EntityState.Modified;
        //        return db.SaveChanges() > 0;
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        public static bool UpdateBalance(this CrmDbContext db, BankAccount account, double amount, BalanceMode balanceMode = BalanceMode.Increment)
        {
            try
            {
                switch (balanceMode)
                {
                case BalanceMode.Increment:
                    account.Balance += amount;
                    break;

                case BalanceMode.Decrement:
                    account.Balance -= amount;
                    break;
                }
                db.Entry(account).State = EntityState.Modified;
                return(db.SaveChanges() > 0);
            }
            catch (Exception ex)
            {
                return(false);
            }
        }