예제 #1
0
        //MAIN

        //TODO:
        //Fields Has_0Drop, Has_1Drop

        //DECK INFO

        //Race fields: Beast, murloc etc
        public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass,
                                                Card.CClass ownClass)
        {
            _comboDic = new Dictionary <string, int>();

            //Load deck
            try
            {
                _myDeck = Bot.CurrentDeck().Cards.Select(card => (Card.Cards)Enum.Parse(typeof(Card.Cards), card)).ToList();
            }
            catch
            {
                _myDeck = new List <Card.Cards>();
            }

            if (BlnDebugMode)
            {
                _myDeck = new List <Card.Cards>()
                {
                    Cards.ShieldSlam,
                    Cards.ShieldSlam,
                    Card.Cards.BOT_299, //Omega Assembly
                    Card.Cards.BOT_299, //Omega Assembly
                    Card.Cards.BOT_042, //Weapons Project
                    Card.Cards.BOT_042, //Weapons Project
                    Cards.Warpath,
                    Cards.Warpath,
                    Cards.CorneredSentry,
                    Cards.CorneredSentry,
                    Cards.DeadMansHand,
                    Cards.DrywhiskerArmorer,
                    Cards.DrywhiskerArmorer,
                    Cards.Execute,
                    Cards.Execute,
                    Cards.AcolyteofPain,
                    Cards.AcolyteofPain,
                    Cards.BloodRazor,
                    Cards.BloodRazor,
                    Cards.HarrisonJones,
                    Cards.Brawl,
                    Cards.Brawl,
                    Card.Cards.BOT_270, //Giggling Inventor
                    Card.Cards.BOT_270, //Giggling Inventor
                    Card.Cards.BOT_238, //Dr. Boom, Mad Genius
                    Cards.GrommashHellscream,
                    Cards.GeosculptorYip,
                    Cards.ScourgelordGarrosh,
                    Cards.TheLichKing,
                    Card.Cards.BOT_069 //The Boomship
                }
            }
            ;

            DeckInfo currentDeckInfo = new DeckInfo(_myDeck);

            //ARCHETYPE DETECTOR

            var archetypes = new List <Archetype>();

            archetypes.AddRange(Bot.GetArchetypes().Where(archetype => archetype.ArchetypeName().Contains("SMK_")));
            Archetype friend = ArchetypeDetector.DetectArchetype(_myDeck, archetypes, 70);

            if (BlnDebugMode)
            {
                string s = "";
                foreach (var card in _myDeck)
                {
                    s += CardTemplate.LoadFromId(card).Name + ", ";
                }
                Bot.Log(s);
            }

            //Choosing ini file
            if (!(Bot.CurrentMode() == Bot.Mode.Arena || Bot.CurrentMode() == Bot.Mode.ArenaAuto))
            {
                AddLog(SDivider);
                if (friend != null)
                {
                    AddLog("Archetype = " + friend.ArchetypeName());
                    var fName = Directory.GetCurrentDirectory() + @"\MulliganProfiles\Files\" + friend.ArchetypeName() +
                                ".ini";
                    if (File.Exists(fName))
                    {
                        _iniTierList = new IniManager(fName);
                    }
                }
                else
                {
                    AddLog("Archetype = NONE");
                }
            }
            IniManager currentFile = _iniTierList;

            string tempString = MulliganInfo();

            if (tempString != null)
            {
                AddLog(tempString);
            }
            else
            {
                AddLog(SDivider);
                AddLog("ERROR!!!");
                AddLog("MULLIGAN IS INSTALLED WRONG");
                AddLog("PLEASE, FOLLOW THE INSTRUCTIONS AT THE TOPIC:");
                AddLog("https://smartbot.ws/index.php?/topic/9020-SMK/&");
                AddLog("Doesn't matter if this is arena mulligan or not.");
                AddLog(SDivider);
                LogDebug();
                PrintLog();
                return(_keep);
            }

            //Setting mode combo preferences
            #region Mode preferences

            int tempCount = -1917;
            int.TryParse(
                currentFile.GetString("combo", "count", "-1917"),
                out tempCount);

            if (tempCount != -1917)
            {
                //Bot.Log("Custom curve: ");
                for (var i = 0; i < tempCount; i++)
                {
                    string tempArgs = currentFile.GetString("combo", string.Format("combo_{0}", i), null);
                    if (tempArgs == null)
                    {
                        continue;
                    }

                    string[] args = tempArgs.Split('*');
                    if (!_comboDic.ContainsKey(args[0]))
                    {
                        //Bot.Log(String.Format("{0} - {1}", args[0], args[1]));
                        _comboDic.Add(args[0], int.Parse(args[1]));
                    }
                }
            }


            if (_comboDic.Count == 0)
            {
                if (Bot.CurrentMode() == Bot.Mode.ArenaAuto || Bot.CurrentMode() == Bot.Mode.Arena) //ARENA
                {
                    _comboDic = new Dictionary <string, int>()
                    {
                        //coin
                        { "12200", 35 },
                        { "12110", 35 },
                        { "12100", 20 },
                        { "11111", 40 },
                        { "11110", 30 },
                        { "11102", 35 },
                        { "11101", 25 },
                        { "11100", 20 },
                        { "11021", 35 },
                        { "11020", 25 },
                        { "11010", 15 },
                        { "10211", 35 },
                        { "10210", 25 },
                        { "10110", 10 },
                        { "10010", 0 },
                        { "10020", 0 },
                        { "10030", -45 },
                        { "10040", -60 },
                        //no coin
                        { "01110", 30 },
                        { "01100", 20 },
                        { "01010", 15 },
                        { "02010", 0 },
                        { "00110", 0 },
                        { "00030", -45 },
                        { "00020", -30 },
                        { "00010", 0 },
                    };
                }
                else //Ranked/Unranked/Practice
                {
                    _comboDic = new Dictionary <string, int>()
                    {
                        //coin
                        { "12200", 30 },
                        { "12100", 0 },
                        { "11111", 40 },
                        { "11110", 30 },
                        { "11102", 35 },
                        { "11101", 25 },
                        { "11100", 20 },
                        { "11021", 35 },
                        { "11020", 25 },
                        { "11010", 15 },
                        { "10211", 35 },
                        { "10210", 25 },
                        { "10030", -45 },
                        { "10040", -60 },
                        //no coin
                        { "01110", 30 },
                        { "01100", 20 },
                        { "01010", 15 },
                        { "02100", -10 },
                    };
                }
            }

            #endregion

            //Define our globals
            _choices       = choices;
            _opponentClass = opponentClass;

            //New class choices
            //var mChoices = new List<Mcard>
            //{
            //    new Mcard(choices[0]),
            //    new Mcard(choices[1]),
            //    new Mcard(choices[2]),
            //};
            //if (choices.Count > 3) mChoices.Add(new Mcard(choices[3]));


            AddLog("Match info: ");
            AddLog("Class: " + ownClass);
            AddLog("Opponent: " + _opponentClass);


            bool coin = _choices.Count >= 4;    //Defines the coin
            if (coin)
            {
                Keep(null, Card.Cards.GAME_005);
            }

            AddLog("Coin: " + coin);
            AddLog(SDivider);

            AddLog("Offered:");
            foreach (var card in _choices)
            {
                AddLog("> " + CardTemplate.LoadFromId(card).Name + " (" + card + ")");
            }
            AddLog(SDivider);

            //LOAD ID

            int[] iCardPts   = new int[_choices.Count];
            int[] iCardCombo = new int[_choices.Count];
            int[,] iCardInteractionPts = new int[_choices.Count, _choices.Count];


            for (var i = 0; i < choices.Count; i++)
            {
                var card = choices[i];

                int.TryParse(_iniTierList.GetString(string.Format("card_{0}", card), "class_ANY", "-50"),
                             out iCardPts[i]);

                int temp;

                int.TryParse(
                    _iniTierList.GetString(string.Format("card_{0}", card), string.Format("class_{0}", ownClass), "-1917"),
                    out temp);

                iCardPts[i] = (temp == -1917) ? iCardPts[i] : temp;

                int.TryParse(
                    _iniTierList.GetString(string.Format("card_{0}", card), "combo", "0"),
                    out iCardCombo[i]);

                int.TryParse(
                    _iniTierList.GetString(string.Format("card_{0}", card), string.Format("opp_{0}", _opponentClass), "0"),
                    out temp);

                iCardPts[i] += temp;

                if (coin)
                {
                    int.TryParse(_iniTierList.GetString(string.Format("card_{0}", card), "coin", "0"), out temp);
                    iCardPts[i] += temp;
                }

                for (var j = 0; j < choices.Count; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }
                    var card2 = choices[j];
                    int.TryParse(
                        _iniTierList.GetString(string.Format("card_{0}", card), string.Format("pCard_{0}", card2),
                                               "0"), out iCardInteractionPts[i, j]);
                }

                int.TryParse(
                    _iniTierList.GetString(string.Format("card_{0}", card), string.Format("opp_{0}", _opponentClass), "0"),
                    out temp);
            }

            int[,,,] combinationPts          = new int[2, 2, 2, 2];
            double[,,,] combinationPtsPerCrd = new double[2, 2, 2, 2];
            bool[,,,] combinationCmb         = new bool[2, 2, 2, 2];
            int[,,,,] combinationInt         = new int[2, 2, 2, 2, 4];
            int[,,,,] combinationCst         = new int[2, 2, 2, 2, 6];

            string bestComboVal        = "0000";
            int    bestComboPts        = 0;
            double bestComboPtsPerCard = 0;
            int    bestCardCount       = 0;

            do
            {
                int[] i = new int[4];

                for (i[0] = 0; i[0] < 2; i[0]++)
                {
                    for (i[1] = 0; i[1] < 2; i[1]++)
                    {
                        for (i[2] = 0; i[2] < 2; i[2]++)
                        {
                            for (i[3] = 0; (i[3] < 2 && coin || i[3] < 1 && !coin); i[3]++)
                            {
                                //List<Card.Cards> currentChoices = new List<Card.Cards>();
                                //for (var it = 0; it < choices.Count; it++)
                                //{
                                //    if (i[it] == 1)
                                //    {
                                //        currentChoices.Add(choices[it]);
                                //    }
                                //}

                                for (var it = 0; it < choices.Count; it++)
                                {
                                    //var card = choices[it];

                                    if (i[it] == 0)
                                    {
                                        continue;
                                    }

                                    combinationPts[i[0], i[1], i[2], i[3]]     += iCardPts[it];
                                    combinationInt[i[0], i[1], i[2], i[3], it] += iCardPts[it];

                                    for (var jt = 0; jt < choices.Count; jt++)
                                    {
                                        if ((jt == it) || (i[jt] == 0))
                                        {
                                            continue;
                                        }

                                        combinationInt[i[0], i[1], i[2], i[3], jt] += iCardInteractionPts[it, jt];
                                        combinationPts[i[0], i[1], i[2], i[3]]     += iCardInteractionPts[it, jt];
                                    }
                                }

                                for (var it = 0; it < choices.Count; it++)
                                {
                                    var card    = choices[it];
                                    var cardTmp = CardTemplate.LoadFromId(card);

                                    if (i[it] == 0)
                                    {
                                        continue;
                                    }

                                    int tmp = cardTmp.Cost;

                                    /* TODO: FIXME: dirty hack */
                                    if (card == Cards.NerubianProphet)
                                    {
                                        tmp = 3;
                                    }
                                    if (card == Cards.CorridorCreeper)
                                    {
                                        tmp = 3;
                                    }
                                    if (card == Cards.MoguFleshshaper)
                                    {
                                        tmp = 4;
                                    }

                                    combinationCst[i[0], i[1], i[2], i[3], Math.Min(5, tmp)]++;
                                }

                                //TODO: MB BETTER TO REWORK COMBO FORMAT
                                var curCombo = string.Format
                                               (
                                    "{0}{1}{2}{3}{4}",
                                    coin ? 1 : 0,
                                    combinationCst[i[0], i[1], i[2], i[3], 1],
                                    combinationCst[i[0], i[1], i[2], i[3], 2],
                                    combinationCst[i[0], i[1], i[2], i[3], 3],
                                    combinationCst[i[0], i[1], i[2], i[3], 4]
                                               );

                                if (_comboDic.ContainsKey(curCombo) && combinationCst[i[0], i[1], i[2], i[3], 5] == 0)
                                {
                                    combinationPts[i[0], i[1], i[2], i[3]] += _comboDic[curCombo];
                                    combinationCmb[i[0], i[1], i[2], i[3]]  = true;

                                    for (int j = 0; j < 4; j++)
                                    {
                                        if (i[j] == 1)
                                        {
                                            combinationPts[i[0], i[1], i[2], i[3]] += iCardCombo[j];
                                        }
                                    }
                                }

                                //Extra cards value reduce
                                if (!combinationCmb[i[0], i[1], i[2], i[3]])
                                {
                                    combinationPts[i[0], i[1], i[2], i[3]] -= combinationCst[i[0], i[1], i[2], i[3], 5] * 150;
                                    combinationPts[i[0], i[1], i[2], i[3]] -= combinationCst[i[0], i[1], i[2], i[3], 4] * 100;
                                    combinationPts[i[0], i[1], i[2], i[3]] -= combinationCst[i[0], i[1], i[2], i[3], 3] * 75;

                                    if (!coin && combinationCst[i[0], i[1], i[2], i[3], 2] > 1)
                                    {
                                        combinationPts[i[0], i[1], i[2], i[3]] -= (combinationCst[i[0], i[1], i[2], i[3], 2] - 1) * 55;
                                    }
                                    else if (coin && combinationCst[i[0], i[1], i[2], i[3], 2] > 2)
                                    {
                                        combinationPts[i[0], i[1], i[2], i[3]] -= (combinationCst[i[0], i[1], i[2], i[3], 2] - 2) * 55;
                                    }
                                    if (!coin && combinationCst[i[0], i[1], i[2], i[3], 1] > 2)
                                    {
                                        combinationPts[i[0], i[1], i[2], i[3]] -= (combinationCst[i[0], i[1], i[2], i[3], 1] - 2) * 30;
                                    }
                                    else if (coin && combinationCst[i[0], i[1], i[2], i[3], 1] > 2)
                                    {
                                        combinationPts[i[0], i[1], i[2], i[3]] -= (combinationCst[i[0], i[1], i[2], i[3], 2] - 1) * 20;
                                    }
                                }
                                if (combinationCst[i[0], i[1], i[2], i[3], 0] > 1)
                                {
                                    combinationPts[i[0], i[1], i[2], i[3]] -= (combinationCst[i[0], i[1], i[2], i[3], 0] - 1) * 20;
                                }

                                /* TODO: FIXME: dirty hack */
                                if ((i[0] == 1 && choices[0] == Cards.CorridorCreeper) ||
                                    (i[1] == 1 && choices[1] == Cards.CorridorCreeper) ||
                                    (i[2] == 1 && choices[2] == Cards.CorridorCreeper) ||
                                    (i[3] == 1 && choices[3] == Cards.CorridorCreeper))
                                {
                                    for (var it = 0; it < choices.Count; it++)
                                    {
                                        if (i[it] == 0)
                                        {
                                            continue;
                                        }
                                        combinationPts[i[0], i[1], i[2], i[3]] += GetTokenCount(choices[it]) * 10;
                                    }
                                }

                                //weapon penalty
                                var weaponCount = choices.Where((t, it) => i[it] == 1 && CardTemplate.LoadFromId(t).Type == Card.CType.WEAPON).Count();
                                if (weaponCount > 1)
                                {
                                    combinationPts[i[0], i[1], i[2], i[3]] -= (weaponCount - 1) * 30;
                                }

                                var cardCount = i[0] + i[1] + i[2] + i[3];
                                if (i[0] + i[1] + i[2] + i[3] != 0)
                                {
                                    combinationPtsPerCrd[i[0], i[1], i[2], i[3]] = (double)combinationPts[i[0], i[1], i[2], i[3]] / cardCount;
                                }

                                if (BlnUserDebugMode)
                                {
                                    AddLog(string.Format("Combination: {0}{1}{2}{3} -- Points: {4,5} -- Pts/Card: {5:###.##}", i[0],
                                                         i[1], i[2], i[3], combinationPts[i[0], i[1], i[2], i[3]], combinationPtsPerCrd[i[0], i[1], i[2], i[3]]));
                                }

                                if (combinationPts[i[0], i[1], i[2], i[3]] >= cardCount * 100 &&
                                    (bestComboPts <combinationPts[i[0], i[1], i[2], i[3]] ||
                                                   bestComboPts == combinationPts[i[0], i[1], i[2], i[3]] &&
                                                   cardCount> bestCardCount))
                                {
                                    bestCardCount       = cardCount;
                                    bestComboPts        = combinationPts[i[0], i[1], i[2], i[3]];
                                    bestComboPtsPerCard = combinationPtsPerCrd[i[0], i[1], i[2], i[3]];
                                    bestComboVal        = string.Format("{0}{1}{2}{3}", i[0], i[1], i[2], i[3]);
                                }
                            }
                        }
                    }
                }
            } while (false);

            AddLog(string.Format("Best Combination: {0} -- Points: {1} -- Pts/Card: {2:###.##}", bestComboVal,
                                 bestComboPts, bestComboPtsPerCard));
            AddLog(SDivider);

            AddLog("Finally keeping:");

            List <Card.Cards> lccKeeping = new List <Card.Cards>();
            for (var i = _choices.Count - 1; i >= 0; i--)
            {
                if (bestComboVal[i] == '1')
                {
                    lccKeeping.Add(_choices[i]);
                }
            }

            foreach (var card in lccKeeping)
            {
                Keep(null, card);
            }

            if (lccKeeping.Count == 0)
            {
                AddLog("Nothing");
            }

            AddLog(SDivider);

            if (BlnUserDebugMode)
            {
                LogDebug();
            }

            //Ending
            PrintLog();

            return(_keep);
        }
    }