private void StartLog() { string tierlistVer = _manager.GetString("info", "version", "unknown"); string tierlistName = _manager.GetString("info", "name", "Basic"); AddLog(Divider); AddLog("MasterwaiMulligan"); AddLog(Divider); AddLog("Tierlist"); AddLog("Version: " + tierlistVer); AddLog("Name: " + tierlistName); AddLog(Divider); AddLog("Curve Importance: " + SimBoard.FourDropMod.ToString("F2")); AddLog("1 Drop Mod: " + SimBoard.OneDropMod.ToString("F2")); AddLog("2 Drop Mod: " + SimBoard.TwoDropMod.ToString("F2")); AddLog("3 Drop Mod: " + SimBoard.ThreeDropMod.ToString("F2")); AddLog("4 Drop Mod: " + SimBoard.FourDropMod.ToString("F2")); AddLog(Divider); AddLog("Match info:"); AddLog("Class: " + _ownClass); AddLog("Opponent: " + _opponentClass); AddLog("Coin: " + _coin); AddLog(Divider); AddLog("Offered:"); foreach (var card in _choices) { var cardTmp = CardTemplate.LoadFromId(card); AddLog("> " + cardTmp.Name); } AddLog(Divider); }
private string MulliganInfo() { string sTierListVersion = _iniTierList.GetString("info", "version", "unknown"); string sTierListName = _iniTierList.GetString("info", "name", "Basic"); string info = "\r\n" + SDivider + "\r\nSoviet " + SName + ":" + sTierListName + "\r\n" + SDivider; info += "\r\nCore version: Build" + SBuild; info += "\r\nTierList version: Build" + sTierListVersion; info += "\r\n" + SDivider; return(info); }
//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); } }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { GetDeck(); var tierlistPath = Directory.GetCurrentDirectory() + @"\MulliganProfiles\MMTierlists\"; if (Bot.CurrentMode() == Bot.Mode.Arena || Bot.CurrentMode() == Bot.Mode.Arena) { var arenaTierlist = _settingsManager.GetString("Decks", "Arena", "NoSetting"); tierlistPath += arenaTierlist == "NoSetting" ? "SovietArena_TierList.ini" : arenaTierlist; } else { var rankedTierList = _settingsManager.GetString("Decks", Bot.CurrentDeck().Name, "NoSetting"); tierlistPath += rankedTierList == "NoSetting" ? "SovietArena_TierList.ini" : rankedTierList; } _manager = new IniManager(tierlistPath); _keep = new List <Card.Cards>(); _opponentClass = opponentClass; _ownClass = ownClass; _choices = choices; _hand = _choices.ToList(); SimBoard.Opponnent = opponentClass; var curveImportance = ParseDouble(_manager.GetString("curve", "curveImportance", "0.5")); var fourDropMod = ParseDouble(_manager.GetString("curve", "fourDropMod", "1")); SimBoard.OneDropMod = ParseDouble(_manager.GetString("curve", "oneDropMod", "4")) / fourDropMod * curveImportance; SimBoard.TwoDropMod = ParseDouble(_manager.GetString("curve", "twoDropMod", "3")) / fourDropMod * curveImportance; SimBoard.ThreeDropMod = ParseDouble(_manager.GetString("curve", "threeDropMod", "2")) / fourDropMod * curveImportance; SimBoard.FourDropMod = curveImportance; _coin = _hand.Count >= 4; if (_coin) { _keep.Add(Card.Cards.GAME_005); _choices.Remove(Card.Cards.GAME_005); _deck.Add(Card.Cards.GAME_005); } _cardInfo = _manager.GetDict(_deck, ownClass); AddLog(Divider); AddLog("Deck:"); foreach (Card.Cards card in _deck) { try { AddLog("V: " + _cardInfo[card].CardPts.ToString().PadLeft(5) + " : " + CardTemplate.LoadFromId(card).Name); } catch (Exception) { // ignored } } StartLog(); string bestComboVal = "0000"; double bestComboPts = double.MinValue; int bestCardCount = 0; var combos = new Variations <bool>(new List <bool> { true, false }, _choices.Count, GenerateOption.WithRepetition); var deck = _deck.ToList(); _hand.ForEach(x => deck.Remove(x)); foreach (var combo in combos) { var comboCards = new List <Card.Cards>(); for (var i = 0; i < _choices.Count; i++) { if (combo[i]) { comboCards.Add(_choices[i]); } } var comboStr = ""; foreach (bool b in combo) { comboStr += b ? 1 : 0; } int count = comboCards.Count; var startingHands = new Combinations <Card.Cards>(deck, _choices.Count - count).Select(x => { var ret = new List <Card.Cards>(x); ret.AddRange(comboCards); if (_coin) { ret.Add(Card.Cards.GAME_005); } return(ret); }).ToList(); double combinationPts = (double)startingHands.Average(x => CurveSim(x)); AddLog(String.Format("Combination: {0} -- Value: {1:###.###}", comboStr, combinationPts)); if (bestComboPts < combinationPts || (Math.Abs(bestComboPts - combinationPts) < 0.01 && count > bestCardCount)) { bestCardCount = count; bestComboPts = combinationPts; bestComboVal = comboStr; } } #region EndLog AddLog(String.Format("Best Combination: {0} -- Value: {1:F3}", bestComboVal, bestComboPts)); AddLog(Divider); AddLog("Finally keeping:"); for (var i = _choices.Count - 1; i >= 0; i--) { if (bestComboVal[i] == '1') { _keep.Add(_choices[i]); var cardTmp = CardTemplate.LoadFromId(_choices[i]); AddLog("> " + cardTmp.Name); } } if (_keep.Count == 0) { AddLog("Nothing"); } AddLog(Divider); #endregion PrintLog(); return(_keep); }