PRoConEvents.MULTIbalancer.SwapSameClanTags C# (CSharp) Method

SwapSameClanTags() private method

private SwapSameClanTags ( List &usScrambled, List &ruScrambled ) : void
usScrambled List
ruScrambled List
return void
        private void SwapSameClanTags(ref List<PlayerModel> usScrambled, ref List<PlayerModel> ruScrambled)
        {
            /*
            Since all players have been moved to squad 0 at this point, only need to swap PlayerModel items
            between the two scramble lists. No actual moving is required.
            */
            DebugScrambler(" ");
            if (KeepFriendsInSameTeam) {
            DebugScrambler("Keeping clan tags and friends to same team");
            } else {
            DebugScrambler("Keeping clan tags to same team");
            }
            try {
            PerModeSettings perMode = GetPerModeSettings();
            String usName = GetTeamName(1);
            String ruName = GetTeamName(2);

            Dictionary<String,int[]> matesDistribution = new Dictionary<String,int[]>();

            // Calculate distribution between the two teams
            foreach (PlayerModel clone in usScrambled) {
            String tagOrFriendex = ExtractTagOrFriendex(clone);
            if (String.IsNullOrEmpty(tagOrFriendex)) continue;
            int[] teamCounts = null;
            if (matesDistribution.TryGetValue(tagOrFriendex, out teamCounts) && teamCounts != null) {
                teamCounts[1] = teamCounts[1] + 1;
            } else {
                teamCounts = new int[3]{0,0,0};
                teamCounts[1] = teamCounts[1] + 1;
                matesDistribution[tagOrFriendex] = teamCounts;
            }
            }
            foreach (PlayerModel clone in ruScrambled) {
            String tagOrFriendex = ExtractTagOrFriendex(clone);
            if (String.IsNullOrEmpty(tagOrFriendex)) continue;
            int[] teamCounts = null;
            if (matesDistribution.TryGetValue(tagOrFriendex, out teamCounts) && teamCounts != null) {
                teamCounts[2] = teamCounts[2] + 1;
            } else {
                teamCounts = new int[3]{0,0,0};
                teamCounts[2] = teamCounts[2] + 1;
                matesDistribution[tagOrFriendex] = teamCounts;
            }
            }

            // Find split tag counts
            List<String> splitTagsOrFriends = new List<String>();
            foreach (String id in matesDistribution.Keys) {
            if (matesDistribution[id][1] == 0) continue;
            if (matesDistribution[id][2] == 0) continue;
            // Split!
            DebugScrambler("Identifier ^b[" + id + "]^n is split: " + matesDistribution[id][1] + "/" + usName + " vs " + matesDistribution[id][2] + "/" + ruName);
            splitTagsOrFriends.Add(id);
            }
            if (splitTagsOrFriends.Count == 0) {
            if (KeepFriendsInSameTeam) {
                DebugScrambler("No clan tags or friends were split");
            } else {
                DebugScrambler("No clan tags were split");
            }
            return;
            }

            // Build squad table
            Dictionary<int,SquadRoster> squads = new Dictionary<int,SquadRoster>();
            foreach (PlayerModel us in usScrambled) {
            int key = (1 * 1000) + us.ScrambledSquad;
            AddPlayerToSquadRoster(squads, us, key, us.ScrambledSquad, false);
            }
            foreach (PlayerModel ru in ruScrambled) {
            int key = (2 * 1000) + ru.ScrambledSquad;
            AddPlayerToSquadRoster(squads, ru, key, ru.ScrambledSquad, false);
            }

            // Swap to maintain squad sizes and team sizes
            int target = 0;
            int opposing = 0;
            List<PlayerModel> targetList = null;
            List<PlayerModel> opposingList = null;
            bool allOk = true;

            foreach (String splitId in splitTagsOrFriends) {
            try {
                DebugScrambler("Working on identifier [^b" + splitId + "^n]");
                // Target team is the one with the majority
                if (matesDistribution[splitId][1] > matesDistribution[splitId][2]) {
                    target = 1;
                    opposing = 2;
                    targetList = usScrambled;
                    opposingList = ruScrambled;
                } else {
                    target = 2;
                    opposing = 1;
                    targetList = ruScrambled;
                    opposingList = usScrambled;
                }
                DebugScrambler("Target team is " + GetTeamName(target) + " with " + matesDistribution[splitId][target] + ", opposing team is " + GetTeamName(opposing) + " with " + matesDistribution[splitId][opposing]);
                // List all squads that have this clan tag or friendex
                List<int> clan = GetSquadsWithClanTagOrFriendex(splitId, squads);
                // List players that need to move
                List<PlayerModel> minority = new List<PlayerModel>();
                List<PlayerModel> replacements = new List<PlayerModel>();
                foreach (int key in clan) {
                    if ((key / 1000) != target) { // squad containing minority clan member from opposing team
                        foreach (PlayerModel mate in squads[key].Roster) {
                            String mId = ExtractTagOrFriendex(mate);
                            if (mId == splitId && !minority.Contains(mate)) minority.Add(mate);
                        }
                    }
                }
                if (minority.Count == 0) {
                    DebugScrambler("ASSERT: No minority clan members for [" + splitId + "]");
                    return;
                }
                // Need a list of replacements from the target team to swap, try non-clan members from target squads first
                foreach (int key in clan) {
                    if ((key / 1000) == target) { // squad containing majority clan members from target team
                        foreach (PlayerModel rep in squads[key].Roster) {
                            String rId = ExtractTagOrFriendex(rep);
                            if (String.IsNullOrEmpty(rId) && !replacements.Contains(rep)) {
                                replacements.Add(rep);
                            }
                            if (replacements.Count == minority.Count) break;
                        }
                    }
                }
                // Might not be any room in target squads, so pick non-tagged extras from end of sorted list
                if (replacements.Count < minority.Count && targetList.Count > 0) {
                    // start at the bottom of the sorted list and go up in metric
                    for (int x = (targetList.Count-1); x >= 0; --x) {
                        if (replacements.Count == minority.Count) break;
                        PlayerModel extra = targetList[x];
                        String xId = ExtractTagOrFriendex(extra);
                        if (String.IsNullOrEmpty(xId) && !replacements.Contains(extra)) {
                            replacements.Add(extra);
                        }
                    }
                }
                // If not enough replacements, abandon minority players until equal
                while (replacements.Count < minority.Count) {
                    if (minority.Count == 0) break;
                    // Not enough replacements
                    PlayerModel mate = minority[0];
                    DebugScrambler("ASSERT: Not enough replacements " + minority.Count + " vs " + replacements.Count + " abandoning " + mate.Name);
                    minority.Remove(mate);
                }
                if (minority.Count == 0 || replacements.Count == 0 || (replacements.Count != minority.Count)) {
                    if (KeepFriendsInSameTeam) {
                        DebugScrambler("Unable to swap clan members or friends to the target team");
                    } else {
                        DebugScrambler("Unable to swap clan members to the target team");
                    }
                    return;
                }
                // Purge the minority movers from the squad table and opposing list
                foreach (PlayerModel mate in minority) {
                    RemovePlayerFromSquadRoster(squads, mate.Name);
                    opposingList = RemovePlayerFromList(opposingList, mate.Name);
                }
                // Purge the replacements from the squad table and target list
                foreach (PlayerModel rep in replacements) {
                    RemovePlayerFromSquadRoster(squads, rep.Name);
                    targetList = RemovePlayerFromList(targetList, rep.Name);
                }
                // Swap the minority movers with the replacements
                int i = 0;
                foreach (PlayerModel mate in minority) {
                    try {
                        PlayerModel extra = replacements[i];
                        String mId = ExtractTagOrFriendex(mate);
                        String xId = ExtractTagOrFriendex(extra);
                        String mateName = (KeepFriendsInSameTeam && !String.IsNullOrEmpty(mId)) ? ("[" + mId + "]" + mate.Name) : (mate.FullName);
                        String extraName = (KeepFriendsInSameTeam && !String.IsNullOrEmpty(xId)) ? ("[" + xId + "]" + extra.Name) : (extra.FullName);
                        DebugScrambler("SWAP: ^b" + mateName + "^n/" + GetTeamName(opposing) + "/" + GetSquadName(mate.ScrambledSquad) + " with ^b" + extraName + "^n/" + GetTeamName(target) + "/" + GetSquadName(extra.ScrambledSquad));
                        int tmpSquad = extra.ScrambledSquad;
                        extra.ScrambledSquad = mate.ScrambledSquad;
                        mate.ScrambledSquad = tmpSquad;
                        extra.Team = opposing;
                        mate.Team = target;

                        targetList.Add(mate);
                        int mateKey = (1000 * mate.Team) + mate.ScrambledSquad;
                        AddPlayerToSquadRoster(squads, mate, mateKey, mate.ScrambledSquad, false);
                        opposingList.Add(extra);
                        int extraKey = (1000 * extra.Team) + extra.ScrambledSquad;
                        AddPlayerToSquadRoster(squads, extra, extraKey, extra.ScrambledSquad, false);
                        DebugScrambler("      Team " + GetTeamName(mate.Team) + " now has ^b" + mateName + "^n in " + GetSquadName(mate.ScrambledSquad) + " squad");
                        DebugScrambler("      Team " + GetTeamName(extra.Team) + " now has ^b" + extraName + "^n in " + GetSquadName(extra.ScrambledSquad) + " squad");
                    } catch (Exception e) {
                        ConsoleException(e);
                    }
                    ++i;
                }
                // Validate
                int maxTeam = perMode.MaxPlayers/2;
                allOk = true;
                if (targetList.Count > maxTeam) {
                    ConsoleDebug("ASSERT: too many players on team " + GetTeamName(target));
                    allOk = false;
                }
                if (opposingList.Count > maxTeam) {
                    ConsoleDebug("ASSERT: too many players on team " + GetTeamName(opposing));
                    allOk = false;
                }
                foreach (PlayerModel extra in opposingList) {
                    String testTag = ExtractTagOrFriendex(extra);
                    if (testTag == splitId) {
                        if (KeepFriendsInSameTeam) {
                            ConsoleDebug("ASSERT: minority clan member or friend not swapped ^b" + extra.FullName + "^n");
                        } else {
                            ConsoleDebug("ASSERT: minority clan member not swapped ^b" + extra.FullName + "^n");
                        }
                        // this is tolerable, so leave allOk set to true
                    }
                }
            } catch (Exception e) {
                ConsoleException(e);
            } finally {
                // Must update the refs passed in
                if (allOk) {
                    if (target == 1) {
                        if (targetList != null) usScrambled = targetList;
                        if (opposingList != null) ruScrambled = opposingList;
                    } else {
                        if (opposingList != null) usScrambled = opposingList;
                        if (targetList != null) ruScrambled = targetList;
                    }
                }
            }
            }
            if (KeepFriendsInSameTeam) {
            DebugScrambler("Done keeping clan members or friends on the same teams!");
            } else {
            DebugScrambler("Done keeping clan members on the same teams!");
            }
            } catch (Exception e) {
            ConsoleException(e);
            } finally {
            DebugScrambler(" ");
            }
        }
MULTIbalancer