예제 #1
0
        // Once Teams are completely balanced, output and save them into an Excel sheet.
        private void save_TeamsExcel(Balance outBalance)
        {
            SaveFileDialog sfd_Excel = new SaveFileDialog();

            sfd_Excel.Filter = "Excel Sheet (*.xlsx)|*.xlsx";
            sfd_Excel.Title  = "Save Teams";
            if (sfd_Excel.ShowDialog() == DialogResult.OK)
            {
                Application.DoEvents();
                Cursor.Current = Cursors.WaitCursor;
                // Make an Excel Sheet
                Excel.Application xlApp = new Excel.Application();
                Excel.Workbook    xlWorkBook;
                Excel.Worksheet   xlWorkSheet;
                object            mis = System.Reflection.Missing.Value;
                xlWorkBook       = xlApp.Workbooks.Add(mis);
                xlWorkSheet      = (Excel.Worksheet)xlWorkBook.ActiveSheet;
                xlWorkSheet.Name = "Teams Balance";
                try {
                    xlWorkSheet.PageSetup.PaperSize   = Excel.XlPaperSize.xlPaper11x17;
                    xlWorkSheet.PageSetup.Orientation = Excel.XlPageOrientation.xlLandscape;
                }
                catch { }

                #region Make Excel Sheet
                xlWorkSheet.Columns["A"].ColumnWidth = 20.00;   // Name
                xlWorkSheet.Columns["B"].ColumnWidth = 20.00;   // Summoner Name
                xlWorkSheet.Columns["C"].ColumnWidth = 20.00;   // Assigned Role
                xlWorkSheet.Columns["D"].ColumnWidth = 15.00;   // Ranking
                xlWorkSheet.Cells[1, 1]            = "Name";
                xlWorkSheet.Cells[1, 2]            = "Summoner Name";
                xlWorkSheet.Cells[1, 3]            = "Assigned Role";
                xlWorkSheet.Cells[1, 4]            = "Ranking";
                xlWorkSheet.Rows[1].Font.Bold      = true;
                xlWorkSheet.Rows[1].Font.Underline = true;
                xlWorkSheet.get_Range("A1", "D1").Cells.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;

                int         row = 3, team = 1;
                List <Role> roleList = new List <Role>(new Role[] {
                    Role.TOP, Role.JNG, Role.MID, Role.ADC, Role.SUP
                });
                Dictionary <Role, string> role2String = new Dictionary <Role, string>()
                {
                    { Role.TOP, "Top" },
                    { Role.JNG, "Jungle" },
                    { Role.MID, "Mid" },
                    { Role.ADC, "ADC" },
                    { Role.SUP, "Support" },
                    { Role.NONE, "None" }
                };
                foreach (Team teamSel in outBalance.teams)
                {
                    xlWorkSheet.Cells[row, 1] = "Team " + team;
                    xlWorkSheet.get_Range("A" + row, "D" + row).Merge();

                    foreach (Role role in roleList)
                    {
                        row++;
                        Player player = teamSel.getPlayerRole(role);
                        xlWorkSheet.Cells[row, 1] = player.name;
                        string ignString = player.ign.ToString();
                        if (player.hasDuo())
                        {
                            ignString += " (D)";
                        }
                        xlWorkSheet.Cells[row, 2] = ignString;
                        string roleString = role2String[player.assignedRole];
                        if (player.isAutoFilled())
                        {
                            roleString += " (Autofilled)";
                        }
                        else if (player.isRoleFilled())
                        {
                            roleString += " (Filled)";
                        }
                        else if (player.isSecondaryAssigned())
                        {
                            roleString += " (Secondary)";
                        }
                        xlWorkSheet.Cells[row, 3] = roleString;
                        string ranking = player.getRank();
                        xlWorkSheet.Cells[row, 4] = ranking;
                        xlWorkSheet.Cells[row, 4].Interior.Color = ColorTranslator.ToOle(MainForm.RankToColor(player.getTier()));
                    }
                    row++; row++; team++;
                }
                #endregion

                releaseObject(xlWorkSheet);
                string filename = sfd_Excel.FileName;
                try {
                    xlApp.DisplayAlerts = false;
                    xlWorkBook.SaveAs(filename);
                    xlApp.Visible = true;
                }
                catch (Exception ex) {
                    MessageBox.Show("Can't overwrite file. Please save it as another name." + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                releaseObject(xlWorkBook);
                releaseObject(xlApp);
                Cursor.Current = Cursors.Default;
            }
        }
예제 #2
0
        // ----- PART 2: MEGA LOOP
        public bool balance(ref RichTextBox rtb)
        {
            int     randSeed = startSeed - 1, currChecks = 0;
            Balance bestBalanceEver = new Balance();
            Balance bestBalanceSeed = new Balance(); // This will store our bestBalance within that seed

            // MEGALOOP: Number of checks has not exceeded maxChecks
            while (currChecks < maxChecks)
            {
                int lowestSeedRange = int.MaxValue;
                currChecks++; randSeed++;
                // Preparations: Make a deep copy of roster that can be edited
                Dictionary <Name, Player> masterList = deepClone(roster);
                // Begin
                Dictionary <Role, List <Player> > assignRoleList = new Dictionary <Role, List <Player> >()
                {
                    { Role.TOP, new List <Player>() },
                    { Role.JNG, new List <Player>() },
                    { Role.MID, new List <Player>() },
                    { Role.ADC, new List <Player>() },
                    { Role.SUP, new List <Player>() },
                };
                // Assign non-Fill Primary Roles
                try {
                    assignRoles(ref masterList, ref assignRoleList, duoList,
                                numTeams, randSeed, true);
                }
                catch (Exception ex) {
                    string msg = "ERROR - Assigning primary roles. " +
                                 "Reason: " + ex.Message;
                    write_ConsoleLog(msg, ref rtb);
                    return(false);
                }
                // Assign non-Fill Secondary Roles
                try {
                    assignRoles(ref masterList, ref assignRoleList, duoList,
                                numTeams, randSeed, false);
                }
                catch (Exception ex) {
                    string msg = "ERROR - Assigning secondary roles. " +
                                 "Reason: " + ex.Message;
                    write_ConsoleLog(msg, ref rtb);
                    return(false);
                }

                // The remaining masterList is now fillList.
                // MASTER-LOOP BEGIN
                while (masterList.Count > 0)
                {
                    // Find role with smallest points, and add a random player
                    Role   addFillRole = roleMinPointsFill(assignRoleList, numTeams);
                    Player addPlayer   = masterList.Values.ToList().Max(); // Greedy approach
                    addPlayer.assignedRole = addFillRole;
                    assignRoleList[addFillRole].Add(addPlayer);
                    masterList.Remove(addPlayer.ign);
                    // Make sure the player does not have the same role as their duo
                    // If so, randomly switch a solo player who is autoFill -> secondary -> Primary
                    // from another role
                    if (containsName(assignRoleList[addFillRole], addPlayer.duo))
                    {
                        Player swapPlayer = aSoloFromRole(assignRoleList, addFillRole, addPlayer, randSeed);
                        // Taking the assumption that the above function also takes into account that the swapped player
                        // is not in the same role as their duo
                        if (swapPlayer.getName() == null)
                        {
                            string msg = "ERROR - " + swapPlayer.getName() + " cannot swap. Too many duos.";
                            write_ConsoleLog(msg, ref rtb);
                            return(false);
                        }
                        Role swapRole = swapPlayer.assignedRole;
                        assignRoleList[swapRole].Remove(swapPlayer);
                        assignRoleList[addFillRole].Remove(addPlayer);
                        swapPlayer.assignedRole = addFillRole;
                        assignRoleList[addFillRole].Add(swapPlayer);
                        addPlayer.assignedRole = swapRole;
                        assignRoleList[swapRole].Add(addPlayer);
                    }
                }
                // MASTER-LOOP END

                bool breakLoop = false;
                foreach (List <Player> roleList in assignRoleList.Values)
                {
                    // If No AutoFill option is selected, check masterList if there is an AutoFill. If so, skip
                    if (noAutoFill)
                    {
                        foreach (Player player in roleList)
                        {
                            if (player.isAutoFilled())
                            {
                                breakLoop = true;
                                string msg = "Seed " + randSeed + " has an Autofill";
                                write_ConsoleLog(msg, ref rtb);
                            }
                        }
                    }
                    // Validation: Should hopefully never occur
                    if (roleList.Count != numTeams)
                    {
                        string msg = "ERROR - assignRoleList does not have " + numTeams + " teams. It might be impossible to form a Balance.";
                        write_ConsoleLog(msg, ref rtb);
                        return(false);
                    }
                }
                if (breakLoop)
                {
                    continue;
                }

                // Initialize the Balance abstract
                Balance currBalance = new Balance(assignRoleList, out lowestSeedRange);
                // All queues acting as a clock queue
                int          currMaxIndex = currBalance.getMaxTeamIndex();
                int          currMinIndex = currBalance.getMinTeamIndex();
                int          rolesRemain  = NUM_ROLES;
                Queue <Role> roleQ        = new Queue <Role>(new Role[] {
                    Role.TOP, Role.JNG, Role.MID, Role.ADC, Role.SUP
                });
                Queue <int> maxIndexQ = new Queue <int>();
                Queue <int> minIndexQ = new Queue <int>();
                for (int i = 0; i < numTeams; ++i)
                {
                    maxIndexQ.Enqueue(i);
                    minIndexQ.Enqueue(i);
                }

                // Conditions:
                // 1) rolesRemaining == 0
                // If lowestRange changes: rolesRemaining set back to 5
                // To move onto the next Role
                // 1) Check every iteration of minTeamIndex (minCheckRemain == 0)
                // 2) Check every iteration of maxTeamIndex (maxCheckRemain == 0)
                // If lowestRange changes: both checkRema counters set back to numTeams
                // ROLE-LOOP BEGIN
                while (rolesRemain > 0)
                {
                    Role checkRole = roleQ.Peek();
                    int  minCheckRemain = numTeams, maxCheckRemain = numTeams;
                    bool minFlag = true;
                    // Check within each Role
                    while (!(minCheckRemain == 0 && maxCheckRemain == 0))
                    {
                        // Work on minIndex first
                        int swapIndex = (minFlag) ? minIndexQ.Peek() : maxIndexQ.Peek();
                        int newRange  = (minFlag) ?
                                        currBalance.switchPlayer(checkRole, currMinIndex, swapIndex) :
                                        currBalance.switchPlayer(checkRole, currMaxIndex, swapIndex);
                        if (newRange < lowestSeedRange)
                        {
                            // Condition 2: New minRange
                            bestBalanceSeed = deepClone(currBalance);
                            currMinIndex    = currBalance.getMinTeamIndex();
                            currMaxIndex    = currBalance.getMaxTeamIndex();
                            lowestSeedRange = newRange;
                            minCheckRemain  = numTeams;
                            maxCheckRemain  = numTeams;
                            rolesRemain     = NUM_ROLES;
                            minFlag         = true;
                        }
                        else
                        {
                            // Condition 3: Continue iterating. Switch currBalance back
                            if (minFlag)
                            {
                                minCheckRemain--;
                                currBalance.switchPlayer(checkRole, currMinIndex, swapIndex);
                            }
                            else
                            {
                                maxCheckRemain--;
                                currBalance.switchPlayer(checkRole, currMaxIndex, swapIndex);
                            }
                            if (minCheckRemain == 0)
                            {
                                minFlag = false;
                            }
                        }
                        // Cycle through the clock queue
                        if (minFlag)
                        {
                            minIndexQ.Dequeue();
                            minIndexQ.Enqueue(swapIndex);
                        }
                        else
                        {
                            maxIndexQ.Dequeue();
                            maxIndexQ.Enqueue(swapIndex);
                        }
                    }
                    // Made it to the end of a complete role check
                    rolesRemain--;
                    roleQ.Dequeue();
                    roleQ.Enqueue(checkRole);
                }
                // ROLE-LOOP END

                // An entire "seedCheck" is finished here
                if (writeRangeConsole)
                {
                    string msg = "Lowest range in Seed " + randSeed + ": " + lowestSeedRange;
                    write_ConsoleLog(msg, ref rtb);
                }
                if (!bestOutput && lowestSeedRange == threshold)
                {
                    DialogResult resultBox = MessageBox.Show("A balance was found with a Range of " + lowestSeedRange + " at seed " + randSeed +
                                                             ".\nWould you like to close and save it? Pressing No continues the balance.",
                                                             "Finished", MessageBoxButtons.YesNoCancel);
                    if (resultBox == DialogResult.Yes)
                    {
                        save_TeamsExcel(bestBalanceSeed);
                        writeTeamPoints(bestBalanceSeed, ref rtb);
                        break;
                    }
                    else if (resultBox == DialogResult.Cancel)
                    {
                        break;
                    }
                }
                else if (bestOutput && lowestSeedRange < bestBalanceEver.getRange())
                {
                    bestBalanceEver = deepClone(bestBalanceSeed);
                }
            }
            // MEGALOOP END
            Cursor.Current = Cursors.Default;

            // If we got to this point, that means bestBalance has our best teams
            if (!bestOutput && bestBalanceSeed.getRange() > threshold)
            {
                MessageBox.Show("Could not find a balance with the desired range of " + threshold + ".");
            }
            else if (bestOutput)
            {
                MessageBox.Show("The best balance possible for this roster is with a Range of " + bestBalanceEver.getRange() +
                                "\nSaving the output.", "Finished", MessageBoxButtons.OK);
                save_TeamsExcel(bestBalanceEver);
                writeTeamPoints(bestBalanceEver, ref rtb);
            }

            return(true);
        }