public List <Card.Cards> HandleMulligan(List <Card.Cards> Choices, Card.CClass opponentClass, Card.CClass ownClass) { var hand = HandleMinions(Choices, _whiteList); _whiteList.AddOrUpdate(Coin, true); _whiteList.AddOrUpdate(HandleWeapons(Choices, hand), false); // only 1 weapon is allowed _whiteList.AddOrUpdate(HandleSpells(Choices, hand), false); // only 1 spell is allowed Bot.Log("Your Card options are"); foreach (var q in Choices) { Bot.Log(CardTemplate.LoadFromId(q.ToString()).ToString()); } Bot.Log(""); Bot.Log("Mulligan pick the following cards to keep "); foreach (var s in from s in Choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { Bot.Log(CardTemplate.LoadFromId(s.ToString()).ToString()); _cardsToKeep.Add(s); } return(_cardsToKeep); }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { GC.Collect(); GC.WaitForPendingFinalizers(); AppDomain domain = AppDomain.CreateDomain("MulliganCoreDomain"); object result = null; try { AssemblyName assemblyName = new AssemblyName { CodeBase = dllPath }; Assembly assembly = domain.Load(assemblyName); Type type = assembly.GetType("HearthstoneMulligan.DllMain"); MethodInfo methodInfo = type.GetMethod("HandleMulligan"); object classInstance = Activator.CreateInstance(type, null); object[] parametersArray = { choices, opponentClass, ownClass }; result = methodInfo.Invoke(classInstance, parametersArray); } finally { AppDomain.Unload(domain); } return((List <Card.Cards>)result); }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//奥尔多侍从 BT_020 int flag2=0;//BAR_875逝者之剑 BAR_875 foreach (Card.Cards card in choices) { if(card==Card.Cards.BT_020//奥尔多侍从 BT_020 ){flag1+=1;} if(card==Card.Cards.BAR_875//逝者之剑逝者之剑 BAR_875 ){flag2+=1;} } foreach (Card.Cards card in choices) { if((card==Card.Cards.BAR_873//圣礼骑士 BAR_873 )){ Keep(card,"圣礼骑士"); } if(card==Card.Cards.BT_019// 莫戈尔·莫戈尔格 BT_019 ){ Keep(card,"莫戈尔·莫戈尔格"); } if(card==Card.Cards.BAR_875// 逝者之剑 BAR_875 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_875)) { Keep(card,"逝者之剑"); } } if(card==Card.Cards.SW_315// 联盟旗手 SW_315 ){ Keep(card,"联盟旗手"); } if(card==Card.Cards.BAR_876// 北卫军指挥官 BAR_876 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_876)&&flag2>0) { Keep(card,"北卫军指挥官"); } } } return CardsToKeep; }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//奥尔多侍从 BT_020 foreach (Card.Cards card in choices) { if(card==Card.Cards.BT_020//奥尔多侍从 BT_020 ){flag1+=1;} } foreach (Card.Cards card in choices) { if((card==Card.Cards.SW_052//探查内鬼 SW_052 )){ Keep(card,"探查内鬼"); } if(card==Card.Cards.BT_701// 间谍女郎 BT_701 ){ Keep(card,"间谍女郎"); } if(card==Card.Cards.SW_418// 军情七处潜伏者 SW_418 ){ Keep(card,"军情七处潜伏者"); } if(card==Card.Cards.SW_413// 军情七处探员 SW_413 ){ Keep(card,"军情七处探员"); } if(card==Card.Cards.SW_413// 军情七处探员 SW_413 ){ if(!CardsToKeep.Contains(Card.Cards.SW_413)) { Keep(card,"军情七处探员"); } } if(card==Card.Cards.EX1_134// 军情七处特工 EX1_134 ){ if(!CardsToKeep.Contains(Card.Cards.EX1_134)) { Keep(card,"军情七处特工"); } } } return CardsToKeep; }
public static List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { InitMulligan(choices, opponentClass, ownClass); Task t_LoadGeneralBlackListEntries = Task.Run(() => { LoadGeneralBlackListEntries(MainLists.OpponentClass, MainLists.OwnClass); }); Task t_LoadOwnBlackListEntries = Task.Run(() => { LoadOwnBlackListEntries(); }); t_LoadGeneralBlackListEntries.Wait(); t_LoadOwnBlackListEntries.Wait(); var detectedDeckType = DeckTypeDetector.SearchForDeckType(); MainLists.CurrentDeckType = detectedDeckType; if (detectedDeckType == DeckTypeDetector.DeckType.UNKNOWN) { CreateDefaultLists(); } else //particular deck type { MainLists.MaxManaCost = 3; DeckTypeDetector.GenerateWhiteAndBlackListForSpecialDeck(detectedDeckType); } CalculateMulligan(MainLists.MaxManaCost); foreach (Task task in neutralMinionTaskList) { task.Wait(); } //DeckCalc CalculateDeckProbabilities(); if (ValueReader.IsCoachModeEnabled && File.Exists(Environment.CurrentDirectory + @"\De.TorstenMandelkow.MetroChart.dll")) { Thread t = new Thread(delegate() { var cWind = new USER_GUI.CoachMode.CoachWindow { Title = $"Mulligan Coach for {MainLists.CurrentDeckType.ToString()}" }; cWind.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); } return(MainLists.chosenCards); }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//港口匪徒 SW_029 int flag2=0;//血帆桨手 CS3_008 foreach (Card.Cards card in choices) { if(card==Card.Cards.SW_029//港口匪徒 SW_029 ){flag1+=1;} if(card==Card.Cards.CS3_008//血帆桨手 CS3_008 ){flag2+=1;} } foreach (Card.Cards card in choices) { if((card==Card.Cards.BAR_843//战歌大使 BAR_843 )){ Keep(card,"战歌大使"); } if(card==Card.Cards.SW_029// 港口匪徒 SW_029 ){ Keep(card,"港口匪徒"); } if(card==Card.Cards.CS3_008// 血帆桨手 CS3_008 ){ Keep(card,"血帆桨手"); } if(card==Card.Cards.BT_121// 被禁锢的甘尔葛 BT_121 ){ if(!CardsToKeep.Contains(Card.Cards.BT_121)) { Keep(card,"被禁锢的甘尔葛"); } } if(card==Card.Cards.BAR_074// 前沿哨所 BAR_074 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_074)) { Keep(card,"前沿哨所"); } } } return CardsToKeep; }
public static bool IsAggroClass(Card.CClass heroClass) { if (heroClass == Card.CClass.HUNTER || heroClass == Card.CClass.MAGE || heroClass == Card.CClass.ROGUE) { return(true); } else { return(false); } }
private static void LoadGeneralBlackListEntries(Card.CClass opponentClass, Card.CClass myClass) { if (opponentClass != Card.CClass.WARRIOR && opponentClass != Card.CClass.HUNTER && opponentClass != Card.CClass.ROGUE) { MainLists.blackList.Add("EX1_007");//Acolyte of Pain } if (opponentClass != Card.CClass.HUNTER) { MainLists.blackList.Add("TU4d_001");//Hemet Nesingwary } if (opponentClass != Card.CClass.WARLOCK) { MainLists.blackList.Add("AT_106"); //Light's Champion } MainLists.blackList.Add("AT_115"); //Fencing Coach MainLists.blackList.Add("EX1_304"); //Void Terror MainLists.blackList.Add("FP1_025"); //Reincarnate MainLists.blackList.Add("CS2_038"); //Ancestral Spirit MainLists.blackList.Add("EX1_349"); //Divine Favor MainLists.blackList.Add("CS2_023"); //Arcane Intellect MainLists.blackList.Add("CS2_011"); //Savage roar MainLists.blackList.Add("EX1_622"); //Shadow Word Death MainLists.blackList.Add("EX1_625"); //Shadow Form MainLists.blackList.Add("DS1_233"); //Mind Blast MainLists.blackList.Add("CS2_108"); //Execute MainLists.blackList.Add("EX1_391"); //Slam MainLists.blackList.Add("EX1_005"); //BGH MainLists.blackList.Add("CS2_007"); //Healing Touch MainLists.blackList.Add("EX1_246"); //Hex MainLists.blackList.Add("EX1_575"); //Mana Tide Totem MainLists.blackList.Add("EX1_539"); //Kill Command MainLists.blackList.Add("CS2_203"); //Ironbeak Owl MainLists.blackList.Add("CS2_118"); //Magma Rager MainLists.blackList.Add("EX1_132"); //Eye for an Eye MainLists.blackList.Add("CS2_231"); //Wisp MainLists.blackList.Add("EX1_294"); //Mirror entity if (opponentClass != Card.CClass.WARLOCK) { MainLists.blackList.Add("EX1_238"); //Lightning Bolt } MainLists.blackList.Add("EX1_565"); //Flametongue Totem MainLists.blackList.Add("EX1_059"); //Crazed Alchemist MainLists.blackList.Add("FP1_003"); //Echoing Ooze MainLists.blackList.Add("GVG_108"); //Recombobulator MainLists.blackList.Add("EX1_049"); //Youthful Brewmaster MainLists.blackList.Add("NEW1_025"); //Bloodsail Corsair MainLists.blackList.Add("CS2_169"); //Young Dragonhawk MainLists.blackList.Add("EX1_408"); //Mortal Strike }
//Get value of certain card in certain class public int GetCardValue(Card.Cards card, Card.CClass friendlyClass) { //Look for value in our class if the card is neutral or from our class. Otherwise look for value in the class that the card belongs to. var cclass = CardTemplate.LoadFromId(card).Class == Card.CClass.NONE ? friendlyClass : CardTemplate.LoadFromId(card).Class; try { //If there is no specific value for the requested class, use neutral value. return((int)Cards.Find(x => x.Id == card).Scores[cclass] == 0 ? (int)Cards.Find(x => x.Id == card).Scores[Card.CClass.NONE] : (int)Cards.Find(x => x.Id == card).Scores[cclass]); } catch (Exception e) { throw new InvalidOperationException("The card " + card + " could not be found in the Tierlist.", e); } }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { var HasCoin = choices.Count >= 4; var WorthyOneDrop = choices.Count(IsWorthyOneDrop); var WorthyTwoDrop = choices.Count(IsWorthyTwoDrop); var WorthyThreeDrop = choices.Count(IsWorthyThreeDrop); var MaxOneDrop = HasCoin && WorthyOneDrop == 2 && WorthyTwoDrop >= 1 && WorthyThreeDrop >= 1 ? 2 : 1; var MaxTwoDrop = (HasCoin && WorthyOneDrop == 0 && WorthyTwoDrop >= 2) || (WorthyTwoDrop >= 2 && WorthyThreeDrop == 0 && WorthyOneDrop == 0 && HasCoin) ? 2 : 1; var MaxThreeDrop = WorthyTwoDrop > 0 ? 1 : 0; var MaxFourDrop = HasCoin && WorthyTwoDrop == 1 && WorthyThreeDrop == 0 ? 1 : 0; Log("---Default mulligan logic-----"); Log(string.Format("Choices : {0} -- Limits : 1:{1} - 2:{2} - 3:{3} - 4:{4}", string.Join(",", choices), MaxOneDrop, MaxTwoDrop, MaxThreeDrop, MaxFourDrop)); choices.ForEach(delegate(Card.Cards cardid) { if (IsWorthyOneDrop(cardid) && CardsToKeep.Count(IsWorthyOneDrop) < MaxOneDrop) { Keep(cardid, string.Format("Kept 1 mana cost : {0}", Load(cardid).Name)); } if (IsWorthyTwoDrop(cardid) && CardsToKeep.Count(IsWorthyTwoDrop) < MaxTwoDrop) { Keep(cardid, string.Format("Kept 2 mana cost : {0}", Load(cardid).Name)); } if (IsWorthyThreeDrop(cardid) && CardsToKeep.Count(IsWorthyThreeDrop) < MaxThreeDrop) { Keep(cardid, string.Format("Kept 3 mana cost : {0}", Load(cardid).Name)); } if (IsWorthyFourDrop(cardid) && CardsToKeep.Count(IsWorthyFourDrop) < MaxFourDrop) { Keep(cardid, string.Format("Kept 4 mana cost : {0}", Load(cardid).Name)); } }); return(CardsToKeep); }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { var CardsToKeep = new List <Card.Cards>(); var HasCoin = choices.Count == 4; var WorthyOneDrop = choices.Count(x => IsWorthyOneDrop(x)); var WorthyTwoDrop = choices.Count(x => IsWorthyTwoDrop(x)); var WorthyThreeDrop = choices.Count(x => IsWorthyThreeDrop(x)); var WorthyFourDrop = choices.Count(x => IsWorthyFourDrop(x)); var MaxOneDrop = HasCoin && WorthyOneDrop == 2 && WorthyTwoDrop >= 1 && WorthyThreeDrop >= 1 ? 2 : 1; var MaxTwoDrop = WorthyOneDrop >= 1 && (WorthyThreeDrop >= 1 || (WorthyFourDrop > 1 && HasCoin)) ? 1 : 3; var MaxThreeDrop = WorthyTwoDrop > 0 ? 1 : 0; var MaxFourDrop = HasCoin && WorthyTwoDrop == 1 ? 1 : 0; choices.ForEach(delegate(Card.Cards cardid) { if (IsWorthyOneDrop(cardid) && CardsToKeep.Count(x => IsWorthyOneDrop(x)) < MaxOneDrop) { CardsToKeep.Add(cardid); } if (IsWorthyTwoDrop(cardid) && CardsToKeep.Count(x => IsWorthyTwoDrop(x)) < MaxTwoDrop) { CardsToKeep.Add(cardid); } if (IsWorthyThreeDrop(cardid) && CardsToKeep.Count(x => IsWorthyThreeDrop(x)) < MaxThreeDrop) { CardsToKeep.Add(cardid); } if (IsWorthyFourDrop(cardid) && CardsToKeep.Count(x => IsWorthyFourDrop(x)) < MaxFourDrop) { CardsToKeep.Add(cardid); } }); return(CardsToKeep); }
//Get value of certain card in certain class public int GetCardValue(Card.Cards card, Card.CClass cclass) { //If there is no specific value for the requested class, use neutral value. try { if ((int)Cards.Find(x => x.Id == card).Scores[cclass] == 0) { return((int)Cards.Find(x => x.Id == card).Scores[Card.CClass.NONE]); } else { return((int)Cards.Find(x => x.Id == card).Scores[cclass]); } } catch (Exception e) { return(0); } finally { } return(0); }
private static void InitMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { List <CardTemplate> choices_BoardCards = choices.Select(x => new BoardCard(x).ResultingBoardCard).ToList(); MainLists.HandCards_BoardCards = choices_BoardCards; MainLists.HandCards_native = choices; try { MainLists.currentDeck = Bot.CurrentDeck(); } catch //MulliganTester.exe doesnt recognize deck :( { MainLists.currentDeck = new Deck(); } AutoUpdateInit.CheckUpdate(); MainLists.chosenCards = new List <Card.Cards>(); MainLists.whiteList = new List <string>(); MainLists.blackList = new List <string>(); MainLists.OwnClass = ownClass; MainLists.OpponentClass = opponentClass; MainLists.CurrentDeckType = DeckTypeDetector.DeckType.UNKNOWN; //BlackListEntries could get whitelisted if good combo => prefer whitelist > blacklist //3+ mana neutral minions are origanizated by the value cuz not listed anywhere int MaxManaCost = ValueReader.MaxManaCost; if ((ownClass == Card.CClass.HUNTER || ownClass == Card.CClass.WARLOCK) && Bot.CurrentMode() != Bot.Mode.Arena && Bot.CurrentMode() != Bot.Mode.ArenaAuto) { MaxManaCost = ValueReader.MaxManaCostWarlockAndHunter; } MainLists.MaxManaCost = MaxManaCost; }
public override List <Card.Cards> HandleMulligan(List <Card.Cards> Choices, Card.CClass opponentClass, Card.CClass ownClass) { bool hasCoin = Choices.Count > 3; bool has2drop = false; bool lazyFlag = false; #region Default Mulligan _whiteList.AddOrUpdate(_abusiveSergeant, false); _whiteList.AddOrUpdate(_argentSquire, true); _whiteList.AddOrUpdate(_coin, true); // Would be nice to keep double if (!antiControlBETA || (opponentClass != Card.CClass.WARRIOR)) { _whiteList.AddOrUpdate(_hauntedCreeper, true); } _whiteList.AddOrUpdate(_knifeJuggler, false); _whiteList.AddOrUpdate(_leperGnome, true); _whiteList.AddOrUpdate(_madScientist, true); _whiteList.AddOrUpdate(_secretkeeper, true); _whiteList.AddOrUpdate(_shieldedMinibot, true); _whiteList.AddOrUpdate(_zombieChow, true); #endregion Default Mulligan #region Class Specific Mulligan if ((Choices.Any(c => c.ToString() == _harvestGolem) || Choices.Any(c => c.ToString() == _shieldedMinibot) || Choices.Any(c => c.ToString() == _madScientist) || Choices.Any(c => c.ToString() == _knifeJuggler) )) { has2drop = true; } if (midrangeSecretPaladin && hasCoin && has2drop) { _whiteList.AddOrUpdate(_pilotedShredder, false); } if (midrangeSecretPaladin) { _whiteList.AddOrUpdate(_avenge, false); } switch (opponentClass) { case Card.CClass.DRUID: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_pilotedShredder, false); } break; } case Card.CClass.HUNTER: { if (coghammerLogic && has2drop) { _whiteList.AddOrUpdate(_coghammer, false); } _whiteList.AddOrUpdate(_annoyatron, false); if (midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(_consecration, false); } else if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_consecration, false); } break; } case Card.CClass.MAGE: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } else { _whiteList.AddOrUpdate(_nobleSacrifice, false); } if (midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(_consecration, false); } else if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_consecration, false); } break; } case Card.CClass.PALADIN: { if (hasCoin || has2drop) { _whiteList.AddOrUpdate(_bloodKnight, false); _whiteList.AddOrUpdate(_ironbeakOwl, false); } _whiteList.AddOrUpdate(_annoyatron, false); _whiteList.AddOrUpdate(_consecration, false); if (midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(_consecration, false); } else if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_consecration, false); } _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } break; } case Card.CClass.PRIEST: { if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } _whiteList.AddOrUpdate(_pilotedShredder, false); break; } case Card.CClass.ROGUE: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } _whiteList.AddOrUpdate(_pilotedShredder, false); break; } case Card.CClass.SHAMAN: { _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } _whiteList.AddOrUpdate(_pilotedShredder, false); break; } case Card.CClass.WARLOCK: { _whiteList.AddOrUpdate(_consecration, false); _whiteList.AddOrUpdate(_musterForBattle, false); break; } case Card.CClass.WARRIOR: { _whiteList.AddOrUpdate(_annoyatron, false); _whiteList.AddOrUpdate(_musterForBattle, false); if (!midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } if (antiControlBETA && hasCoin) { _whiteList.AddOrUpdate(_pilotedShredder, true); } else { _whiteList.AddOrUpdate(_pilotedShredder, false); } break; } } if (mysteriousChallenger_forever) { _whiteList.AddOrUpdate(_mysteriousChallenger, false); } if ((Choices.Any(c => c.ToString() == _coghammer) && (coghammerLogic && has2drop) && (opponentClass != Card.CClass.WARRIOR))) { _whiteList.AddOrUpdate(_coghammer, false); } else if ((opponentClass == Card.CClass.WARRIOR) || (opponentClass == Card.CClass.PRIEST) || (opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) { _whiteList.AddOrUpdate(_truesilverChamption, false); } if ((competitiveMustard && lazyFlag) && (Choices.Any(c => c.ToString() == _competitiveSpirit) && Choices.Any(c => c.ToString() == _musterForBattle))) { _whiteList.AddOrUpdate(_musterForBattle, false); _whiteList.AddOrUpdate(_competitiveSpirit, false); } //Keep Mysterious Challenger on coin if (hasCoin && !midrangeSecretPaladin) { _whiteList.AddOrUpdate(_annoyatron, false); _whiteList.AddOrUpdate(_mysteriousChallenger, false); } // Redemption and Harvest Golem are kept if you have both. if (redeeming2Drops && (Choices.Any(c => c.ToString() == _harvestGolem) || Choices.Any(c => c.ToString() == _shieldedMinibot) )) { _whiteList.AddOrUpdate(_harvestGolem, false); _whiteList.AddOrUpdate(_redemption, false); // has2drop = true; } if ((opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) //These classes can kill Defender if it's played on turn 1. { nobleJuggler = false; } // Noble Sacrifice is kept if you have Knife Juggler. if (nobleJuggler && (Choices.Any(c => c.ToString() == _knifeJuggler))) { _whiteList.AddOrUpdate(_nobleSacrifice, false); } // Tech choice with blood knight if (keepBloodKnight_onCurve && (Choices.Any(c => c.ToString() == _argentSquire) && (Choices.Any(c => c.ToString() == _shieldedMinibot) || Choices.Any(c => c.ToString() == _annoyatron)))) { _whiteList.AddOrUpdate(_annoyatron, false); _whiteList.AddOrUpdate(_bloodKnight, false); } //Experimental segment that keeps noble sac and avenge with secret keeper. if (vengefulSecretKeeper && (Choices.Any(c => c.ToString() == _avenge) && (Choices.Any(c => c.ToString() == _secretkeeper) && Choices.Any(c => c.ToString() == _nobleSacrifice)))) { _whiteList.AddOrUpdate(_nobleSacrifice, false); _whiteList.AddOrUpdate(_avenge, false); } #endregion foreach (Card.Cards s in from s in Choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { _cardsToKeep.Add(s); } return(_cardsToKeep); }
public List <Card.Cards> HandleMulligan(List <Card.Cards> Choices, Card.CClass opponentClass, Card.CClass ownClass) { var hand = HandleMinions(Choices, _whiteList); _whiteList.AddOrUpdate(Coin, true); _whiteList.AddOrUpdate(HandleWeapons(Choices, hand), false); // only 1 weapon is allowed _whiteList.AddOrUpdate(HandleSpells(Choices, hand), false); // only 1 spell is allowed using (System.IO.StreamWriter file = new System.IO.StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\MulliganProfiles\\MulliganChoicesArchive.txt", true)) { file.WriteLine("Your Card options were:"); var temp = CardTemplate.TemplateList; foreach (var q in Choices) { file.WriteLine(CardTemplate.LoadFromId(q.ToString()).Cost + " mana card: " + CardTemplate.LoadFromId(q.ToString()).Name); } file.WriteLine(""); file.WriteLine("Mulligan pick the following cards to keep "); foreach (var s in from s in Choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { file.WriteLine(CardTemplate.LoadFromId(s.ToString()).Cost + " mana card: " + CardTemplate.LoadFromId(s.ToString()).Name); _cardsToKeep.Add(s); } file.WriteLine("--------------------------------------"); file.WriteLine("Your average deck mana cost is " + Bot.CurrentDeck().Cards.Average(c => CardTemplate.LoadFromId(c).Cost)); file.WriteLine("--------------------------------------"); file.WriteLine("----Your alternative options in your deck were: "); var allOneDrops = (from q in Bot.CurrentDeck().Cards select CardTemplate.LoadFromId(q.ToString()) into qq where qq.Cost == 1 && !qq.IsSecret select qq.Name).ToList(); var allTwoDrops = (from q in Bot.CurrentDeck().Cards select CardTemplate.LoadFromId(q.ToString()) into qq where qq.Cost == 2 && !qq.IsSecret select qq.Name).ToList(); var allThreeDrops = (from q in Bot.CurrentDeck().Cards select CardTemplate.LoadFromId(q.ToString()) into qq where qq.Cost == 3 && !qq.IsSecret select qq.Name).ToList(); var allFourDrops = (from q in Bot.CurrentDeck().Cards select CardTemplate.LoadFromId(q.ToString()) into qq where qq.Cost == 4 && !qq.IsSecret select qq.Name).ToList(); file.WriteLine("------------One Drops:--"); foreach (var c in allOneDrops) { file.WriteLine(c); } file.WriteLine("------------Two Drops:--"); foreach (var c in allTwoDrops) { file.WriteLine(c); } file.WriteLine("------------Three Drops:--"); foreach (var c in allThreeDrops) { file.WriteLine(c); } file.WriteLine("------------Four Drops:--"); foreach (var c in allFourDrops) { file.WriteLine(c); } file.WriteLine( "============================================================================================"); file.WriteLine( "============================================================================================"); file.WriteLine("END OF MULLIGAN AGAINST " + opponentClass + " As a " + ownClass); file.WriteLine( "============================================================================================"); file.WriteLine( "============================================================================================"); file.Close(); } return(_cardsToKeep); }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool hasCoin = choices.Count > 3; bool has2Drop = (choices.Any(c => c.ToString() == HarvestGolem) || choices.Any(c => c.ToString() == ShieldedMinibot) || choices.Any(c => c.ToString() == MadScientist) || choices.Any(c => c.ToString() == KnifeJuggler)); bool lazyFlag = false; #region Default Mulligan _whiteList.AddOrUpdate(AbusiveSergeant, false); _whiteList.AddOrUpdate(ArgentSquire, true); _whiteList.AddOrUpdate(Coin, true); // Would be nice to keep double if (opponentClass != Card.CClass.WARRIOR) { _whiteList.AddOrUpdate(HauntedCreeper, true); } _whiteList.AddOrUpdate(KnifeJuggler, false); _whiteList.AddOrUpdate(LeperGnome, true); _whiteList.AddOrUpdate(MadScientist, true); _whiteList.AddOrUpdate(Secretkeeper, true); _whiteList.AddOrUpdate(ShieldedMinibot, true); _whiteList.AddOrUpdate(ZombieChow, true); #endregion Default Mulligan if (_midrangeSecretPaladin && hasCoin && has2Drop) { _whiteList.AddOrUpdate(PilotedShredder, false); } if (_midrangeSecretPaladin) { _whiteList.AddOrUpdate(Avenge, false); } switch (opponentClass) { case Card.CClass.DRUID: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(PilotedShredder, false); } break; } case Card.CClass.HUNTER: { if (CoghammerLogic && has2Drop) { _whiteList.AddOrUpdate(Coghammer, false); } _whiteList.AddOrUpdate(Annoyatron, false); if (_midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(Consecration, false); } else if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(Consecration, false); } break; } case Card.CClass.MAGE: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } else { _whiteList.AddOrUpdate(NobleSacrifice, false); } if (_midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(Consecration, false); } else if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(Consecration, false); } break; } case Card.CClass.PALADIN: { if (hasCoin || has2Drop) { _whiteList.AddOrUpdate(BloodKnight, false); _whiteList.AddOrUpdate(IronbeakOwl, false); } _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(Consecration, false); if (_midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(Consecration, false); } else if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(Consecration, false); } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } break; } case Card.CClass.PRIEST: { if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.ROGUE: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.SHAMAN: { _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.WARLOCK: { _whiteList.AddOrUpdate(Consecration, false); _whiteList.AddOrUpdate(MusterForBattle, false); break; } case Card.CClass.WARRIOR: { _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, hasCoin); break; } } if (MysteriousChallengerForever) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } if ((choices.Any(c => c.ToString() == Coghammer) && (CoghammerLogic && has2Drop) && (opponentClass != Card.CClass.WARRIOR))) { _whiteList.AddOrUpdate(Coghammer, false); } else if ((opponentClass == Card.CClass.WARRIOR) || (opponentClass == Card.CClass.PRIEST) || (opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) { _whiteList.AddOrUpdate(TruesilverChamption, false); } if ((CompetitiveMustard && lazyFlag) && (choices.Any(c => c.ToString() == CompetitiveSpirit) && choices.Any(c => c.ToString() == MusterForBattle))) { _whiteList.AddOrUpdate(MusterForBattle, false); _whiteList.AddOrUpdate(CompetitiveSpirit, false); } //Keep Mysterious Challenger on coin if (hasCoin && !_midrangeSecretPaladin && MysteriousChallengerCoin) { _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(MysteriousChallenger, false); } // Redemption and Harvest Golem are kept if you have both. if (Redeeming2Drops && (choices.Any(c => c.ToString() == HarvestGolem) || choices.Any(c => c.ToString() == ShieldedMinibot) )) { _whiteList.AddOrUpdate(HarvestGolem, false); _whiteList.AddOrUpdate(Redemption, false); // has2drop = true; } if ((opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) //These classes can kill Defender if it's played on turn 1. { _nobleJuggler = false; } // Noble Sacrifice is kept if you have Knife Juggler. if (_nobleJuggler && (choices.Any(c => c.ToString() == KnifeJuggler))) { _whiteList.AddOrUpdate(NobleSacrifice, false); } // Tech choice with blood knight if (KeepBloodKnightOnCurve && (choices.Any(c => c.ToString() == ArgentSquire) && (choices.Any(c => c.ToString() == ShieldedMinibot) || choices.Any(c => c.ToString() == Annoyatron)))) { _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(BloodKnight, false); } //Experimental segment that keeps noble sac and avenge with secret keeper. if (VengefulSecretKeeper && (choices.Any(c => c.ToString() == Avenge) && (choices.Any(c => c.ToString() == Secretkeeper) && choices.Any(c => c.ToString() == NobleSacrifice)))) { _whiteList.AddOrUpdate(NobleSacrifice, false); _whiteList.AddOrUpdate(Avenge, false); } #endregion foreach (Card.Cards s in from s in choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { _cardsToKeep.Add(s); } return(_cardsToKeep); }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//奥尔多侍从 BT_020 int flag2=0;//BAR_875逝者之剑 BAR_875 int flag3=0;//古神在上 DMF_236 int DRUID=0; int HUNTER=0; int MAGE=0; int PALADIN=0; int PRIEST=0; int ROGUE=0; int SHAMAN=0; int WARLOCK=0; int WARRIOR=0; int DEMONHUNTER=0; foreach (Card.Cards card in choices) { if(card==Card.Cards.BT_020//奥尔多侍从 BT_020 ){flag1+=1;} if(card==Card.Cards.BAR_873//圣礼骑士 BAR_873 ){flag1+=1;} if(card==Card.Cards.BAR_875//逝者之剑逝者之剑 BAR_875 ){flag2+=1;} if(card==Card.Cards.DMF_236//古神在上 DMF_236 ){flag3+=1;} } // foreach (Card.Cards EnemyClass in opponentClass) // { // if(EnemyClass == Card.CClass.PALADIN//奥尔多侍从 BT_020 // ){flag1+=1;} // if(card==Card.Cards.BAR_873//圣礼骑士 BAR_873 // ){flag1+=1;} // if(card==Card.Cards.BAR_875//逝者之剑逝者之剑 BAR_875 // ){flag2+=1;} // if(card==Card.Cards.DMF_236//古神在上 DMF_236 // ){flag3+=1;} // } Bot.Log("对阵职业"+opponentClass); if(opponentClass==Card.CClass.PALADIN){ PALADIN+=1; } if(opponentClass==Card.CClass.DRUID){ DRUID+=1; } if(opponentClass==Card.CClass.HUNTER){ HUNTER+=1; } if(opponentClass==Card.CClass.MAGE){ MAGE+=1; } if(opponentClass==Card.CClass.PRIEST){ PRIEST+=1; } if(opponentClass==Card.CClass.ROGUE){ ROGUE+=1; } if(opponentClass==Card.CClass.SHAMAN){ SHAMAN+=1; } if(opponentClass==Card.CClass.WARLOCK){ WARLOCK+=1; } if(opponentClass==Card.CClass.WARRIOR){ WARRIOR+=1; } if(opponentClass==Card.CClass.DEMONHUNTER){ DEMONHUNTER+=1; } foreach (Card.Cards card in choices) { if((card==Card.Cards.BAR_873//圣礼骑士 BAR_873 )){ Keep(card,"圣礼骑士"); } if((card==Card.Cards.BT_019//莫戈尔·莫戈尔格 BT_019 )){ Keep(card,"莫戈尔·莫戈尔格"); } if(card==Card.Cards.BT_020// 奥尔多侍从 BT_020 ){ Keep(card,"奥尔多侍从"); } if(card==Card.Cards.BT_019// 莫戈尔·莫戈尔格 BT_019 ){ Keep(card,"莫戈尔·莫戈尔格"); } if(card==Card.Cards.BT_292// 阿达尔之手 BT_292 ){ if(!CardsToKeep.Contains(Card.Cards.BT_292)&&flag1>=1) { Keep(card,"阿达尔之手"); } } if(card==Card.Cards.SCH_247// 新生入学 SCH_247 ){ if(!CardsToKeep.Contains(Card.Cards.SCH_247)) { Keep(card,"新生入学"); } } if(card==Card.Cards.DMF_236//古神在上 DMF_236 ){ if(!CardsToKeep.Contains(Card.Cards.DMF_236)) { Keep(card,"古神在上"); } } if(card==Card.Cards.BAR_875// 逝者之剑 BAR_875 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_875)) { Keep(card,"逝者之剑"); } } if(card==Card.Cards.BT_025// 智慧圣契 BT_025 ){ if(!CardsToKeep.Contains(Card.Cards.BT_025)) { Keep(card,"智慧圣契"); } } if(card==Card.Cards.BAR_074// 前沿哨所 BAR_074 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_074)) { Keep(card,"前沿哨所"); } } if(card==Card.Cards.SW_315// 联盟旗手 SW_315 ){ if(!CardsToKeep.Contains(Card.Cards.SW_315)) { Keep(card,"联盟旗手"); } } if(card==Card.Cards.BAR_876// 北卫军指挥官 BAR_876 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_876)&&flag2+flag3>0) { Keep(card,"北卫军指挥官"); } } if(card==Card.Cards.BT_026// 奥尔多真理追寻者 BT_026 ){ if(!CardsToKeep.Contains(Card.Cards.BT_026)) { Keep(card,"奥尔多真理追寻者"); } } if(card==Card.Cards.BAR_075// 十字路口哨所 BAR_075 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_075)&&MAGE+ROGUE>0) { Keep(card,"十字路口哨所"); } } if(card==Card.Cards.SCH_311// 活化扫帚 SCH_311 ){ if(!CardsToKeep.Contains(Card.Cards.SCH_311)&&DRUID>0) { Keep(card,"活化扫帚"); } } if(card==Card.Cards.BAR_078&&HUNTER+SHAMAN+DRUID>0// 剑圣萨穆罗 BAR_078 ){ Keep(card,"剑圣萨穆罗"); } if(card==Card.Cards.BT_024&&HUNTER+SHAMAN>0&&flag1>0// 希望圣契 BT_024 ){ Keep(card,"希望圣契"); } if(card==Card.Cards.SCH_526&&DRUID>0// 巴罗夫领主 SCH_526 ){ Keep(card,"巴罗夫领主"); } } return CardsToKeep; }
/// <summary> /// Supported deck arthetypes: /// Mech Warrior /// </summary> /// <param name="choices"></param> /// <param name="whiteList"></param> /// <param name="opponentClass"></param> /// <param name="coin"></param> private static void MulliganWarrior(List <Card.Cards> choices, IDictionary <string, bool> whiteList, Card.CClass opponentClass, bool coin) { var gotWeapon = false; var control = false; var oneDrop = false; var twoDrop = false; var threeDrop = false; var weapons = new List <string>(); foreach (var c in choices) { var temp = CardTemplate.LoadFromId(c.ToString()); if (!gotWeapon && temp.Type == SmartBot.Plugins.API.Card.CType.WEAPON && temp.Cost == 2) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), false); gotWeapon = true; } if (temp.Race == SmartBot.Plugins.API.Card.CRace.MECH) { if (temp.Cost == 1) { oneDrop = true; whiteList.AddOrUpdate(c.ToString(), false); } if (temp.Cost == 2) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), false); } if (temp.Cost == 3) { threeDrop = true; whiteList.AddOrUpdate(c.ToString(), false); } } if (temp.Type != SmartBot.Plugins.API.Card.CType.WEAPON && temp.Cost <= 3 && temp.Type != SmartBot.Plugins.API.Card.CType.SPELL && temp.Race != SmartBot.Plugins.API.Card.CRace.MECH) { whiteList.AddOrUpdate(c.ToString(), false); } switch (opponentClass) { case Card.CClass.SHAMAN: control = true; break; case Card.CClass.PRIEST: control = true; break; case Card.CClass.MAGE: //control = true; break; case Card.CClass.PALADIN: break; case Card.CClass.WARRIOR: control = true; break; case Card.CClass.WARLOCK: control = true; break; case Card.CClass.HUNTER: break; case Card.CClass.ROGUE: control = true; break; case Card.CClass.DRUID: control = true; break; default: throw new ArgumentOutOfRangeException("opponentClass", opponentClass, null); } if (!control) { continue; } //var curve = twoDrop && threeDrop; if (temp.Type != SmartBot.Plugins.API.Card.CType.WEAPON && twoDrop && temp.Cost == 4 && temp.Race == SmartBot.Plugins.API.Card.CRace.MECH && temp.Atk > 3) { whiteList.AddOrUpdate(c.ToString(), false); } //if (coin && temp.Quality == SmartBot.Plugins.API.Card.CQuality.Epic) // _whiteList.AddOrUpdate(c.ToString(),false); } foreach (var c in from c in choices let temp = CardTemplate.LoadFromId(c.ToString()) where !gotWeapon && temp.Type == SmartBot.Plugins.API.Card.CType.WEAPON && temp.Cost > 2 && temp.Cost < 5 select c) { gotWeapon = true; whiteList.AddOrUpdate(c.ToString(), false); break; } }
public List <Card.Cards> HandleMulligan(List <Card.Cards> Choices, Card.CClass opponentClass, Card.CClass ownClass) { var hasCoin = Choices.Count > 3; _whiteList.AddOrUpdate(Coin, true); #region Class Specific Mulligan switch (ownClass) { case Card.CClass.DRUID: { break; } case Card.CClass.HUNTER: { break; } case Card.CClass.MAGE: { MulliganMage(Choices, _whiteList, opponentClass, hasCoin); break; } case Card.CClass.PALADIN: { break; } case Card.CClass.PRIEST: { break; } case Card.CClass.ROGUE: { break; } case Card.CClass.SHAMAN: { MulliganShaman(Choices, _whiteList, opponentClass, hasCoin, _removalSpells); break; } case Card.CClass.WARLOCK: { break; } case Card.CClass.WARRIOR: { MulliganWarrior(Choices, _whiteList, opponentClass, hasCoin); break; } } #endregion foreach (var s in from s in Choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { _cardsToKeep.Add(s); } return(_cardsToKeep); }
/// <summary> /// Mech Mages /// </summary> /// <param name="choices"></param> /// <param name="whiteList"></param> /// <param name="opponentClass"></param> /// <param name="hasCoin"></param> private static void MulliganMage(List <Card.Cards> choices, Dictionary <string, bool> whiteList, Card.CClass opponentClass, bool hasCoin) { var control = false; var oneDrop = false; var twoDrop = false; var threeDrop = false; var curve = false; CardTemplate oneManaMinion = null; foreach (var c in choices) { var temp = CardTemplate.LoadFromId(c.ToString()); if (temp.Race == SmartBot.Plugins.API.Card.CRace.MECH) { if (temp.Cost == 1) { oneManaMinion = CardTemplate.LoadFromId(c.ToString()); } if (temp.Cost == 2) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), true); } } if (temp.Race != SmartBot.Plugins.API.Card.CRace.MECH && temp.Quality != SmartBot.Plugins.API.Card.CQuality.Epic && temp.Type != SmartBot.Plugins.API.Card.CType.SPELL) //minions handler { if (temp.Cost == 1 && temp.Race != SmartBot.Plugins.API.Card.CRace.MECH) { oneDrop = true; whiteList.AddOrUpdate(c.ToString(), false); } if (temp.Cost == 2) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), true); } } switch (opponentClass) { case Card.CClass.SHAMAN: control = true; break; case Card.CClass.PRIEST: control = true; break; case Card.CClass.MAGE: break; case Card.CClass.PALADIN: { if (temp.Cost == 3 && temp.Quality == SmartBot.Plugins.API.Card.CQuality.Epic) { whiteList.AddOrUpdate(c.ToString(), false); } break; } case Card.CClass.WARRIOR: control = true; break; case Card.CClass.WARLOCK: control = true; break; case Card.CClass.HUNTER: break; case Card.CClass.ROGUE: control = true; break; case Card.CClass.DRUID: control = true; break; default: throw new ArgumentOutOfRangeException("opponentClass", opponentClass, null); } if (temp.Type == SmartBot.Plugins.API.Card.CType.SPELL && temp.Cost == 2) { whiteList.AddOrUpdate(c.ToString(), false); } if (!control) { if (temp.Type == SmartBot.Plugins.API.Card.CType.SPELL && temp.Cost == 1) { whiteList.AddOrUpdate(c.ToString(), false); } continue; } if (temp.Cost == 4 && temp.Race == SmartBot.Plugins.API.Card.CRace.MECH && temp.Atk > 3) { whiteList.AddOrUpdate(c.ToString(), false); } } foreach (var c in from c in choices let temp = CardTemplate.LoadFromId(c.ToString()) where twoDrop && temp.Cost == 3 && temp.Type == SmartBot.Plugins.API.Card.CType.MINION select c) { threeDrop = true; whiteList.AddOrUpdate(c.ToString(), hasCoin); } curve = twoDrop && threeDrop; if (oneManaMinion != null && (!oneDrop && oneManaMinion.Cost == 1)) { whiteList.AddOrUpdate("GVG_082", false); } if (!threeDrop && !hasCoin) { return; } if (MMFelRever && threeDrop && hasCoin && choices.Any(c => c.ToString() == "GVG_016")) { whiteList.AddOrUpdate("GVG_016", false); } if (choices.Any(c => c.ToString() == "GVG_004") && threeDrop || curve) { whiteList.AddOrUpdate("GVG_004", false); } }
/// <summary> /// </summary> /// <param name="choices"></param> /// <param name="whiteList"></param> /// <param name="opponentClass"></param> /// <param name="hasCoin"></param> /// <param name="removalSpells"></param> private static void MulliganShaman(List <Card.Cards> choices, Dictionary <string, bool> whiteList, Card.CClass opponentClass, bool hasCoin, List <string> removalSpells) { //var gotWeapon = false; var control = false; var oneDrop = false; var twoDrop = false; var threeDrop = false; foreach (var c in choices) { var temp = CardTemplate.LoadFromId(c.ToString()); if (temp.Race == SmartBot.Plugins.API.Card.CRace.TOTEM && temp.Cost == 2 && temp.Atk != 0) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), hasCoin); } switch (opponentClass) { case Card.CClass.SHAMAN: control = true; break; case Card.CClass.PRIEST: control = true; break; case Card.CClass.MAGE: //control = true; break; case Card.CClass.PALADIN: break; case Card.CClass.WARRIOR: control = true; break; case Card.CClass.WARLOCK: { whiteList.AddOrUpdate("EX1_245", false); //earth shock because I assume it's a handlock control = true; } break; case Card.CClass.HUNTER: break; case Card.CClass.ROGUE: control = true; break; case Card.CClass.DRUID: // I assume that druids on the ladder are aggro //control = true; break; default: throw new ArgumentOutOfRangeException("opponentClass", opponentClass, null); } if (temp.Type == SmartBot.Plugins.API.Card.CType.MINION && temp.Quality != SmartBot.Plugins.API.Card.CQuality.Epic) { if (temp.Cost == 1) { oneDrop = true; whiteList.AddOrUpdate(c.ToString(), !control); } if (temp.Cost == 2 && temp.Atk > 0) { twoDrop = true; whiteList.AddOrUpdate(c.ToString(), false); } if (!control && temp.Cost == 3 && temp.Atk > 1) { threeDrop = true; whiteList.AddOrUpdate(c.ToString(), hasCoin); } } var curve = twoDrop || threeDrop && hasCoin; if (curve && temp.Cost == 4 && temp.Atk > 3) { whiteList.AddOrUpdate(c.ToString(), false); } } foreach (var c in choices) { var temp = CardTemplate.LoadFromId(c.ToString()); if (temp.Type != SmartBot.Plugins.API.Card.CType.SPELL) { continue; } if (control && temp.Cost == 1) { whiteList.AddOrUpdate(c.ToString(), false); } if (!control && temp.Cost == 3 && !removalSpells.Contains(c.ToString())) { whiteList.AddOrUpdate(c.ToString(), false); } } }
public override void OnHandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { _latestOffered = choices.ToList(); }
//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) { bool HasCoin = choices.Count >= 4; int flag1=0;//哀嚎蒸汽 Wailing Vapor ID:WC_042 int flag2=0;//火光元素 Kindling Elemental ID:BAR_854 int flag3=0;//花岗岩熔铸体 Granite Forgeborn ID:SW_032 int flag4=0;//敲狼锤 Whack-A-Gnoll Hammer ID:DMF_705 int flag5=0;//笼斗管理员 Cagematch Custodian ID:DMF_704 int flag6=0;//旱地风暴 Arid Stormer ID:BAR_045 int flag7=0;//凶恶的雨云 Menacing Nimbus ID:CORE_BOT_533 int flag8=0;//拍卖行木槌 Auctionhouse Gavel ID:SW_025 int flag9=0;//前沿哨所 Far Watch Post ID:BAR_074 int flag10=0;//莫尔杉哨所 Mor'shan Watch Post ID:BAR_076 foreach (Card.Cards card in choices) { if(card==Card.Cards.WC_042//哀嚎蒸汽 Wailing Vapor ID:WC_042 ){flag1+=1;} if(card==Card.Cards.BAR_854//火光元素 Kindling Elemental ID:BAR_854 ){flag2+=1;} if(card==Card.Cards.SW_032//花岗岩熔铸体 Granite Forgeborn ID:SW_032 ID:SW_032 || card==Card.Cards.SW_032//花岗岩熔铸体 Granite Forgeborn ID:SW_032 ID:SW_032 ){flag3+=1;} if(card==Card.Cards.DMF_705 //敲狼锤 Whack-A-Gnoll Hammer ID:DMF_705 ){flag4+=1;} if(card==Card.Cards.DMF_704//笼斗管理员 Cagematch Custodian ID:DMF_704 ){flag5+=1;} if(card==Card.Cards.BAR_045//旱地风暴 Arid Stormer ID:BAR_045 ){flag6+=1;} if(card==Card.Cards.CORE_BOT_533//凶恶的雨云 Menacing Nimbus ID:CORE_BOT_533 ){flag7+=1;} if(card==Card.Cards.SW_025//拍卖行木槌 Auctionhouse Gavel ID:SW_025 ){flag8+=1;} if(card==Card.Cards.BAR_074//前沿哨所 Far Watch Post ID:BAR_074 ){flag9+=1;} if(card==Card.Cards.BAR_076//莫尔杉哨所 Mor'shan Watch Post ID:BAR_076 ){flag10+=1;} } foreach (Card.Cards card in choices) { if((card==Card.Cards.SW_032//花岗岩熔铸体 Granite Forgeborn ID:SW_032 ID:SW_032 )){ { if(!CardsToKeep.Contains(Card.Cards.SW_032)) { Keep(card,"留1花岗岩熔铸体"); } } }//留一张花岗岩熔铸体 if(card==Card.Cards.BAR_854//火光元素 Kindling Elemental ID:BAR_854 ) { Keep(card,"留2火光元素 "); } if(card==Card.Cards.WC_042//哀嚎蒸汽 Wailing Vapor ID:WC_042 ) { Keep(card,"留2哀嚎蒸汽 "); } if(card==Card.Cards.DMF_705//敲狼锤 Whack-A-Gnoll Hammer ID:DMF_705 ) { if(!CardsToKeep.Contains(Card.Cards.DMF_705)&&flag6>=1) { Keep(card,"留1敲狼锤 "); } } if(card==Card.Cards.DMF_704//笼斗管理员 Cagematch Custodian ID:DMF_704 ) { Keep(card,"留2笼斗管理员 "); } if(card==Card.Cards.BAR_074//前沿哨所 Far Watch Post ID:BAR_074 ) { Keep(card,"留2前沿哨所 "); } if(card==Card.Cards.BAR_045//旱地风暴 Arid Stormer ID:BAR_045 ) { if(!CardsToKeep.Contains(Card.Cards.BAR_045)&&flag1+flag2>=1) { Keep(card,"留1旱地风暴 "); } } if(card==Card.Cards.BAR_076//莫尔杉哨所 Mor'shan Watch Post ID:BAR_076 ) { if(!CardsToKeep.Contains(Card.Cards.BAR_076)&&flag1+flag2>=1) { Keep(card,"留1莫尔杉哨所 "); } } // if(card==Card.Cards.WC_005//原初地下城历险家 Primal Dungeoneer ID:WC_005 // ) // { // if(!CardsToKeep.Contains(Card.Cards.WC_005)) // { // Keep(card,"留1原初地下城历险家"); // } // } if(card==Card.Cards.CORE_BOT_533//凶恶的雨云 Menacing Nimbus ID:CORE_BOT_533 ) { Keep(card,"留2凶恶的雨云 "); } if(card==Card.Cards.SW_025//拍卖行木槌 Auctionhouse Gavel ID:SW_025 ) { Keep(card,"留2拍卖行木槌 "); } // if(card==Card.Cards.BT_292//阿达尔之手 Hand of A'dal ID:BT_292 // ){ // if(!CardsToKeep.Contains(Card.Cards.BT_292) // ) // { // Keep(card,"留一张阿达尔之手"); // } // } // if(card==Card.Cards.YOP_031//螃蟹骑士 Crabrider ID:YOP_031 // ){ // if(!CardsToKeep.Contains(Card.Cards.YOP_031) // && HasCoin==true) // { // Keep(card,"后手留一张螃蟹骑士"); // } // } // if(card==Card.Cards.DMF_194//赤鳞驯龙者 Redscale Dragontamer ID:DMF_194 // ){ // if(!CardsToKeep.Contains(Card.Cards.DMF_194) // && HasCoin==true) // { // Keep(card,"后手留一张赤鳞驯龙者 Redscale Dragontamer"); // } // } // if(card==Card.Cards.CORE_FP1_007//蛛魔之卵 Nerubian Egg ID:CORE_FP1_007 // ){ // { // if(!CardsToKeep.Contains(Card.Cards.CORE_FP1_007) // ) // { // Keep(card,"留一张蛛魔之卵 Nerubian Egg"); // } // } //蛛魔之卵 Nerubian Egg ID:CORE_FP1_007 // } // if(card==Card.Cards.DMF_704//笼斗管理员 Cagematch Custodian ID:DMF_704 // ){ // if(!CardsToKeep.Contains(Card.Cards.DMF_704) // && HasCoin==true) // { // Keep(card,"后手留一张莫戈尔·莫戈尔格 Murgur Murgurgle"); // } // else // { // if(!CardsToKeep.Contains(Card.Cards.DMF_704) // && flag1+flag2+flag3>=1 // ) // { // Keep(card,"先手有1费留一张莫戈尔·莫戈尔格 Murgur Murgurgle"); // } // } //笼斗管理员 Cagematch Custodian ID:DMF_704 // } // //留第一张逝者之剑 Sword of the Fallen ID:BAR_875 // if(card==Card.Cards.BAR_875) // { // if(!CardsToKeep.Contains(Card.Cards.BAR_875)) // { // Keep(card,"留第一张逝者之剑 Sword of the Fallen"); // } // } // //有逝者之剑 Sword of the Fallen ID:BAR_875留北卫军指挥官 Northwatch Commander ID:BAR_876 // if(card==Card.Cards.BAR_876 && flag7>=1 // && HasCoin==true // ) // {Keep(card,"后手有逝者之剑 Sword of the Fallen留北卫军指挥官 Northwatch Commander");} } return CardsToKeep; }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//棱彩珠宝工具 SW_048 foreach (Card.Cards card in choices) { if(card==Card.Cards.SW_048//棱彩珠宝工具 SW_048 ){flag1+=1;} if(card==Card.Cards.SW_315//联盟旗手 SW_315 ){flag1+=1;} } foreach (Card.Cards card in choices) { if(card==Card.Cards.SW_048// 棱彩珠宝工具 SW_048 ){ if(!CardsToKeep.Contains(Card.Cards.SW_048)) { Keep(card,"棱彩珠宝工具"); } } if(card==Card.Cards.SW_315// 联盟旗手 SW_315 ){ if(!CardsToKeep.Contains(Card.Cards.SW_315)) { Keep(card,"联盟旗手"); } } if(card==Card.Cards.BT_019// 莫戈尔·莫戈尔格 BT_019 ){ Keep(card,"莫戈尔·莫戈尔格"); } if(card==Card.Cards.BAR_873// 圣礼骑士 BAR_873 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_873)) { Keep(card,"圣礼骑士"); } } if(card==Card.Cards.BOT_270t// 吵吵机器人 BOT_270t ){ if(!CardsToKeep.Contains(Card.Cards.BOT_270t)) { Keep(card,"吵吵机器人"); } } if(card==Card.Cards.CORE_ICC_038// 正义保护者 CORE_ICC_038 ){if(!CardsToKeep.Contains(Card.Cards.CORE_ICC_038)) { Keep(card,"正义保护者"); }} if(card==Card.Cards.CORE_EX1_008//银色侍从 CORE_EX1_008 ){ if(!CardsToKeep.Contains(Card.Cards.CORE_EX1_008)) { Keep(card,"银色侍从"); } } } return CardsToKeep; }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//棱彩珠宝工具 SW_048 foreach (Card.Cards card in choices) { if(card==Card.Cards.SW_048//棱彩珠宝工具 SW_048 ){flag1+=1;} if(card==Card.Cards.SW_315//联盟旗手 SW_315 ){flag1+=1;} } foreach (Card.Cards card in choices) { if(card==Card.Cards.SW_450// 巫师的计策 SW_450 ){ Keep(card,"巫师的计策"); } if(card==Card.Cards.SCH_270// 始生研习 SCH_270 ){ if(!CardsToKeep.Contains(Card.Cards.SCH_270)) { Keep(card,"始生研习"); } } if(card==Card.Cards.SW_108// 初始之火 SW_108 ){ if(!CardsToKeep.Contains(Card.Cards.SW_108)) { Keep(card,"初始之火"); } } if(card==Card.Cards.SCH_509// 冰冷智慧 SCH_509 ){ if(!CardsToKeep.Contains(Card.Cards.SCH_509)) { Keep(card,"冰冷智慧"); } } if(card==Card.Cards.BAR_541// 符文宝珠 BAR_541 ){ if(!CardsToKeep.Contains(Card.Cards.BAR_541)) { Keep(card,"符文宝珠"); } } if(card==Card.Cards.SW_110//点燃 SW_110 ){ if(!CardsToKeep.Contains(Card.Cards.SW_110)) { Keep(card,"符文宝珠"); } } if(card==Card.Cards.CORE_EX1_289//寒冰护体 CORE_EX1_289 ){ if(!CardsToKeep.Contains(Card.Cards.CORE_EX1_289)) { Keep(card,"寒冰护体"); } } if(card==Card.Cards.BT_002//咒术洪流 BT_002 ){ if(!CardsToKeep.Contains(Card.Cards.BT_002)) { Keep(card,"咒术洪流"); } } } return CardsToKeep; }
public List <Card.Cards> HandleMulligan(List <Card.Cards> Choices, Card.CClass opponentClass, Card.CClass ownClass) { bool hasCoin = Choices.Count > 3; bool ancientOwl = false; //Ancient watcher + ironbeak Owl bool strongHand = false; //Giants and Drakes in hand. bool goodHand = false; bool terribleHand = false; bool voidcaller = false; // _whiteList.AddOrUpdate(_coin, true); //Strong hand is only used against slow matchups if (Choices.Any(c => c.ToString() == _mountainGiant) && Choices.Any(c => c.ToString() == _twilightDrake)) { strongHand = true; } //only 1 good 4 drop if (Choices.Any(c => c.ToString() == _mountainGiant) || Choices.Any(c => c.ToString() == _twilightDrake)) { goodHand = true; } //Check if Voidcaller is in hands if (Choices.Any(c => c.ToString() == _voidCaller)) { voidcaller = true; } //Check if there are no good drops in the opening hand if (Choices.All(c => c.ToString() != _mountainGiant) && Choices.All(c => c.ToString() != _twilightDrake) && Choices.All(c => c.ToString() != _ancientWatcher) && Choices.All(c => c.ToString() != _sunfuryProtector) && !Choices.Any(c => c.ToString() == _voidCaller)) { _whiteList.AddOrUpdate(_moltenGiant, true); terribleHand = true; } switch (opponentClass) { case Card.CClass.DRUID: { _whiteList.AddOrUpdate(_mountainGiant, true); _whiteList.AddOrUpdate(_hellfire, false); _whiteList.AddOrUpdate(_ancientWatcher, false); _whiteList.AddOrUpdate(_defenderofArgus, false); _whiteList.AddOrUpdate(_voidCaller, false); if (hasCoin) { //_whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_twilightDrake, true); } else { _whiteList.AddOrUpdate(_twilightDrake, false); } if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 2, 3, 4); // MG LJ DG DI } break; } case Card.CClass.HUNTER: { _whiteList.AddOrUpdate(_zombieChow, true); _whiteList.AddOrUpdate(_mortalCoil, false); _whiteList.AddOrUpdate(_moltenGiant, true); _whiteList.AddOrUpdate(_sunfuryProtector, false); _whiteList.AddOrUpdate(_acidicSwampOoze, true); _whiteList.AddOrUpdate(_ancientWatcher, false); _whiteList.AddOrUpdate(_darkbomb, false); break; } case Card.CClass.MAGE: { _whiteList.AddOrUpdate(_mortalCoil, false); _whiteList.AddOrUpdate(_ironbeakOwl, false); _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_darkbomb, false); _whiteList.AddOrUpdate(_hellfire, false); _whiteList.AddOrUpdate(_sunfuryProtector, false); _whiteList.AddOrUpdate(_voidCaller, false); if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 4, 3, 2); // MG LJ DG DI } _whiteList.AddOrUpdate(_ancientWatcher, false); break; } case Card.CClass.PALADIN: { _whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_zombieChow, true); _whiteList.AddOrUpdate(_mortalCoil, false); _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_hellfire, false); _whiteList.AddOrUpdate(_moltenGiant, true); _whiteList.AddOrUpdate(_mountainGiant, false); _whiteList.AddOrUpdate(_sunfuryProtector, false); if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 4, 3, 2); // MG LJ DG DI } _whiteList.AddOrUpdate(_ancientWatcher, false); break; } case Card.CClass.PRIEST: { _whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_mountainGiant, true); _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_darkbomb, false); _whiteList.AddOrUpdate(_ironbeakOwl, false); if (hasCoin && strongHand) { _whiteList.AddOrUpdate(_emperorThaurissan, false); } if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 5, 3, 2); // MG LJ DG DI } break; } case Card.CClass.ROGUE: { _whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_mountainGiant, true); _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_darkbomb, false); if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 4, 3, 2); } break; } case Card.CClass.SHAMAN: { _whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_zombieChow, true); _whiteList.AddOrUpdate(_ancientWatcher, true); _whiteList.AddOrUpdate(_darkbomb, false); _whiteList.AddOrUpdate(_hellfire, false); _whiteList.AddOrUpdate(_sunfuryProtector, false); _whiteList.AddOrUpdate(_moltenGiant, true); if (voidcaller) //not optimized yet { findGoodDemon(Choices, 1, 2, 3, 4); // MG LJ DG DI } break; } case Card.CClass.WARLOCK: { _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_darkbomb, false); _whiteList.AddOrUpdate(_hellfire, false); _whiteList.AddOrUpdate(_sunfuryProtector, false); _whiteList.AddOrUpdate(_bigGameHunter, false); _whiteList.AddOrUpdate(_moltenGiant, true); if ((Choices.Any(c => c.ToString() == _mortalCoil) && Choices.Any(c => c.ToString() == _ironbeakOwl))) { _whiteList.AddOrUpdate(_ironbeakOwl, false); _whiteList.AddOrUpdate(_mortalCoil, false); } _whiteList.AddOrUpdate(_ancientWatcher, false); break; } case Card.CClass.WARRIOR: { _whiteList.AddOrUpdate(_voidCaller, false); _whiteList.AddOrUpdate(_ancientWatcher, true); _whiteList.AddOrUpdate(_darkbomb, false); if (goodHand) { _whiteList.AddOrUpdate(_acidicSwampOoze, false); } _whiteList.AddOrUpdate(_twilightDrake, true); _whiteList.AddOrUpdate(_mountainGiant, true); _whiteList.AddOrUpdate(_ironbeakOwl, false); if (hasCoin && strongHand) { _whiteList.AddOrUpdate(_emperorThaurissan, false); } if (voidcaller) { findGoodDemon(Choices, 1, 4, 3, 2); // MG LJ DG DI } break; } case Card.CClass.NONE: break; case Card.CClass.JARAXXUS: break; default: throw new ArgumentOutOfRangeException("opponentClass", opponentClass, null); } foreach (var s in from s in Choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { _cardsToKeep.Add(s); } return(_cardsToKeep); }
public List<Card.Cards> HandleMulligan(List<Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { bool HasCoin = choices.Count >= 4; int flag1=0;//雷霆绽放 SCH_427 int flag2=0;//集合石 WC_028 int flag3=0;//伯尔纳·锤喙 SW_115 int flag4=0;//前沿哨所 BAR_074 int flag5=0;//笼斗管理员 DMF_704 int flag6=0;//魔杖工匠 SCH_160 int flag7=0;//原初地下城历险家 WC_005 int flag8=0;//小巧玩具 SW_034 int flag9=0;//异变轮转 DMF_700 int flag10=0;//闪金镇豺狼人 SW_062 foreach (Card.Cards card in choices) { if(card==Card.Cards.SCH_427//雷霆绽放 SCH_427 ){flag1+=1;} if(card==Card.Cards.WC_028//集合石 WC_028 ){flag2+=1;} if(card==Card.Cards.SW_115//伯尔纳·锤喙 SW_115 ){flag3+=1;} if(card==Card.Cards.BAR_074 //前沿哨所 BAR_074 ){flag4+=1;} if(card==Card.Cards.DMF_704//笼斗管理员 DMF_704 ){flag5+=1;} if(card==Card.Cards.SCH_160//魔杖工匠 SCH_160 ){flag6+=1;} if(card==Card.Cards.WC_005//原初地下城历险家 WC_005 ){flag7+=1;} if(card==Card.Cards.SW_034//小巧玩具 SW_034 ){flag8+=1;} if(card==Card.Cards.DMF_700//异变轮转 DMF_700 ){flag9+=1;} if(card==Card.Cards.SW_062//闪金镇豺狼人 SW_062 ){flag10+=1;} } foreach (Card.Cards card in choices) { if((card==Card.Cards.SCH_427//雷霆绽放 SCH_427 )){ { if(!CardsToKeep.Contains(Card.Cards.SCH_427) && (HasCoin==true||flag7>=1)) { Keep(card,"雷霆绽放"); } } } if((card==Card.Cards.SW_034//小巧玩具 SW_034 )){ { if(!CardsToKeep.Contains(Card.Cards.SW_034) && HasCoin==true) { Keep(card,"小巧玩具"); } } } if((card==Card.Cards.SW_062//闪金镇豺狼人 SW_062 )){ { if(!CardsToKeep.Contains(Card.Cards.SW_062) && (HasCoin==true||flag2>=1)) { Keep(card,"闪金镇豺狼人"); } } } if(card==Card.Cards.WC_028//集合石 WC_028 ) { if(!CardsToKeep.Contains(Card.Cards.WC_028)) { Keep(card,"集合石"); } } if(card==Card.Cards.DMF_700//异变轮转 DMF_700 ) { if(!CardsToKeep.Contains(Card.Cards.DMF_700)) { Keep(card,"异变轮转"); } } if(card==Card.Cards.BAR_074//前沿哨所 BAR_074 ) { if(!CardsToKeep.Contains(Card.Cards.BAR_074)) { Keep(card,"前沿哨所"); } } if(card==Card.Cards.DMF_704//笼斗管理员 DMF_704 ) { if(!CardsToKeep.Contains(Card.Cards.DMF_704)) { Keep(card,"笼斗管理员"); } } if(card==Card.Cards.SCH_160//魔杖工匠 SCH_160 ) { if(!CardsToKeep.Contains(Card.Cards.SCH_160)) { Keep(card,"魔杖工匠"); } } if(card==Card.Cards.WC_005//原初地下城历险家 WC_005 ) { if(!CardsToKeep.Contains(Card.Cards.WC_005)) { Keep(card,"原初地下城历险家"); } } if(card==Card.Cards.SW_031//原初地下城历险家 SW_031 ) { Keep(card,"号令元素"); } if(card==Card.Cards.WC_020//原初地下城历险家 SW_031 ) { Keep(card,"火"); } // if(card==Card.Cards.SW_115//伯尔纳·锤喙 SW_115 // ) // { // Keep(card,"伯尔纳·锤喙"); // } } return CardsToKeep; }
//MAIN //TODO: //Fields Has_0Drop, Has_1Drop //DECK INFO //Fields Deck_Has_No_2Drop, Deck_Has_No_3Drop //Field no_rptd_cards //Race fields: Beast, murloc etc public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { try { _myDeck = Bot.CurrentDeck().Cards.Select(card => (Card.Cards)Enum.Parse(typeof(Card.Cards), card)).ToList(); } catch { _myDeck = new List <Card.Cards> { Cards.AzureDrake, Cards.SirFinleyMrrgglton }; } AddLog(MulliganInfo()); //Define our globals _choices = choices; _opponentClass = opponentClass; AddLog("Match info: "); AddLog("Class: " + ownClass); AddLog("Opponent: " + _opponentClass); //Defines the coin. bool coin = _choices.Count >= 4; if (coin) { Keep(null, Card.Cards.GAME_005); } AddLog("Coin: " + coin); AddLog(SDivider); AddLog("Offered:"); foreach (var card in _choices) { var cardTmp = CardTemplate.LoadFromId(card); AddLog("> " + cardTmp.Name); } AddLog(SDivider); //LOAD ID int[] iCardPts = 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), 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[, , ,] combinationPts = new int[2, 2, 2, 2]; int[, , ,] combinationPtsPerCrd = new int[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; int bestComboPtsPerCard = 0; int bestCardCount = 0; for (var i = 0; i < 2; i++) { for (var j = 0; j < 2; j++) { for (var k = 0; k < 2; k++) { for (var l = 0; (l < 2 && coin || l < 1 && !coin); l++) { for (var it = 0; it < choices.Count; it++) { //var card = choices[it]; if ((it == 0 && i == 0) || (it == 1 && j == 0) || (it == 2 && k == 0) || (it == 3 && l == 0)) { continue; } combinationPts[i, j, k, l] += iCardPts[it]; combinationInt[i, j, k, l, it] += iCardPts[it]; for (var jt = 0; jt < choices.Count; jt++) { if ((jt == it) || (jt == 0 && i == 0) || (jt == 1 && j == 0) || (jt == 2 && k == 0) || (jt == 3 && l == 0)) { continue; } //var card2 = choices[jt]; combinationInt[i, j, k, l, jt] += iCardInteractionPts[it, jt]; combinationPts[i, j, k, l] += iCardInteractionPts[it, jt]; } } for (var it = 0; it < choices.Count; it++) { var card = choices[it]; var cardTmp = CardTemplate.LoadFromId(card); if ((it == 0 && i == 0) || (it == 1 && j == 0) || (it == 2 && k == 0) || (it == 3 && l == 0)) { continue; } int tmp = cardTmp.Cost; /* FIXME: dirty hack */ if (card == Cards.NerubianProphet) { tmp = 3; } combinationCst[i, j, k, l, Math.Min(5, tmp)]++; } //int ptsNcPerCard = combinationPts[i, j, k, l] / (i+j+k+l+1); //TODO: MB BETTER TO REWORK COMBO var curCombo = String.Format("{0}{1}{2}{3}{4}", coin ? 1 : 0, //0 combinationCst[i, j, k, l, 1], //1 combinationCst[i, j, k, l, 2], //2 combinationCst[i, j, k, l, 3], //3 combinationCst[i, j, k, l, 4]); //4 if (_comboDic.ContainsKey(curCombo) && combinationCst[i, j, k, l, 5] == 0) { combinationPts[i, j, k, l] += _comboDic[curCombo]; combinationCmb[i, j, k, l] = true; } if (!combinationCmb[i, j, k, l]) { combinationPts[i, j, k, l] -= combinationCst[i, j, k, l, 5] * 150; combinationPts[i, j, k, l] -= combinationCst[i, j, k, l, 4] * 100; combinationPts[i, j, k, l] -= combinationCst[i, j, k, l, 3] * 75; if (!coin && combinationCst[i, j, k, l, 2] > 1) { combinationPts[i, j, k, l] -= (combinationCst[i, j, k, l, 2] - 1) * 55; } else if (coin && combinationCst[i, j, k, l, 2] > 2) { combinationPts[i, j, k, l] -= (combinationCst[i, j, k, l, 2] - 2) * 55; } if (!coin && combinationCst[i, j, k, l, 1] > 2) { combinationPts[i, j, k, l] -= (combinationCst[i, j, k, l, 1] - 2) * 30; } else if (coin && combinationCst[i, j, k, l, 1] > 2) { combinationPts[i, j, k, l] -= (combinationCst[i, j, k, l, 2] - 1) * 20; } } var cardCount = i + j + k + l; if (i + j + k + l != 0) { combinationPtsPerCrd[i, j, k, l] = combinationPts[i, j, k, l] / cardCount; } if (BlnDebugMode) { AddLog(String.Format("Combination: {0}{1}{2}{3} -- Points: {4,5} -- Pts/Card: {5}", i, j, k, l, combinationPts[i, j, k, l], combinationPtsPerCrd[i, j, k, l])); } if (combinationPts[i, j, k, l] >= cardCount * 100 && (bestComboPts <combinationPts[i, j, k, l] || bestComboPts == combinationPts[i, j, k, l] && cardCount> bestCardCount)) { bestCardCount = cardCount; bestComboPts = combinationPts[i, j, k, l]; bestComboPtsPerCard = combinationPtsPerCrd[i, j, k, l]; bestComboVal = String.Format("{0}{1}{2}{3}", i, j, k, l); } } } } } 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 (BlnDebugMode) { LogDebug(); } //Ending PrintLog(); return(_keep); }
public List <Card.Cards> HandleMulligan(List <Card.Cards> choices, Card.CClass opponentClass, Card.CClass ownClass) { var hasCoin = choices.Count > 3; var has2Drop = (choices.Any(c => c.ToString() == ShieldedMinibot) || choices.Any(c => c.ToString() == MadScientist) || choices.Any(c => c.ToString() == KnifeJuggler)); var lazyFlag = false; #region Default Mulligan /*Prevent any sort of reduntant custom logics*/ FixRedundancy(); _whiteList.AddOrUpdate(AbusiveSergeant, false); _whiteList.AddOrUpdate(ArgentSquire, true); _whiteList.AddOrUpdate(Coin, true); // Would be nice to keep double if (opponentClass != Card.CClass.WARRIOR) { _whiteList.AddOrUpdate(HauntedCreeper, false); } _whiteList.AddOrUpdate(KnifeJuggler, false); _whiteList.AddOrUpdate(LeperGnome, true); _whiteList.AddOrUpdate(MadScientist, true); _whiteList.AddOrUpdate(Secretkeeper, false); _whiteList.AddOrUpdate(ShieldedMinibot, true); _whiteList.AddOrUpdate(ZombieChow, true); _whiteList.AddOrUpdate(has2Drop ? HarvestGolem:"", false); _whiteList.AddOrUpdate(choices.Any(c => c.ToString() == KnifeJuggler) ? MusterForBattle: "", false); #endregion Default Mulligan _whiteList.AddOrUpdate(_midrangeSecretPaladin ? Avenge : "", false); _whiteList.AddOrUpdate(_mysteriousChallengerForever ? MysteriousChallenger : "", false); _whiteList.AddOrUpdate(_mysteriousChallengerCoin && hasCoin ? MysteriousChallenger : "", false); _whiteList.AddOrUpdate((_nobleJuggler && (choices.Any(c => c.ToString() == KnifeJuggler))) ? NobleSacrifice : "", false); _whiteList.AddOrUpdate(choices.Any(c => c.ToString() == ShieldedMinibot) && Redeeming2Drops ? Redemption : "", false); switch (opponentClass) { case Card.CClass.DRUID: { lazyFlag = hasCoin; _whiteList.AddOrUpdate(MusterForBattle, false); _whiteList.AddOrUpdate(!_midrangeSecretPaladin ? PilotedShredder : "", false); break; } case Card.CClass.HUNTER: { _whiteList.AddOrUpdate((CoghammerLogic && has2Drop) ? Coghammer : "", false); _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate((!_midrangeSecretPaladin && hasCoin) ? Consecration : "", false); break; } case Card.CClass.MAGE: { lazyFlag = hasCoin; _whiteList.AddOrUpdate(MusterForBattle, false); _whiteList.AddOrUpdate(!_midrangeSecretPaladin && !_neverMysteriousChallenger ? MysteriousChallenger : NobleSacrifice, false); _whiteList.AddOrUpdate(_midrangeSecretPaladin && hasCoin ? Consecration : "", false); break; } case Card.CClass.PALADIN: { _whiteList.AddOrUpdate(hasCoin || has2Drop ? BloodKnight : "", false); _whiteList.AddOrUpdate(hasCoin || has2Drop ? IronbeakOwl : "", false); _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(Consecration, false); if (_midrangeSecretPaladin && hasCoin) { _whiteList.AddOrUpdate(Consecration, false); } else if (!_midrangeSecretPaladin) { _whiteList.AddOrUpdate(Consecration, false); } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin && !_neverMysteriousChallenger) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } break; } case Card.CClass.PRIEST: { _whiteList.AddOrUpdate(!_midrangeSecretPaladin && !_neverMysteriousChallenger ? MysteriousChallenger : "", false); _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.ROGUE: { if (hasCoin) { lazyFlag = true; } _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin && !_neverMysteriousChallenger) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.SHAMAN: { _whiteList.AddOrUpdate(MusterForBattle, false); _whiteList.AddOrUpdate(PilotedShredder, false); break; } case Card.CClass.WARLOCK: { _whiteList.AddOrUpdate(Consecration, false); _whiteList.AddOrUpdate(MusterForBattle, false); break; } case Card.CClass.WARRIOR: { _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(MusterForBattle, false); if (!_midrangeSecretPaladin && hasCoin && !_neverMysteriousChallenger) { _whiteList.AddOrUpdate(MysteriousChallenger, false); } _whiteList.AddOrUpdate(PilotedShredder, hasCoin); break; } } if ((choices.Any(c => c.ToString() == Coghammer) && (CoghammerLogic && has2Drop) && (opponentClass != Card.CClass.WARRIOR))) { _whiteList.AddOrUpdate(Coghammer, false); } else if ((opponentClass == Card.CClass.WARRIOR) || (opponentClass == Card.CClass.PRIEST) || (opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) { _whiteList.AddOrUpdate(TruesilverChamption, false); } if ((CompetitiveMustard && lazyFlag) && (choices.Any(c => c.ToString() == CompetitiveSpirit) && choices.Any(c => c.ToString() == MusterForBattle))) { _whiteList.AddOrUpdate(MusterForBattle, false); _whiteList.AddOrUpdate(CompetitiveSpirit, false); } if (hasCoin && !_midrangeSecretPaladin && _mysteriousChallengerCoin) { _whiteList.AddOrUpdate(Annoyatron, false); _whiteList.AddOrUpdate(MysteriousChallenger, false); } if ((opponentClass == Card.CClass.ROGUE) || (opponentClass == Card.CClass.DRUID)) //These classes can kill Defender if it's played on turn 1. { _nobleJuggler = false; } #endregion foreach (var s in from s in choices let keptOneAlready = _cardsToKeep.Any(c => c.ToString() == s.ToString()) where _whiteList.ContainsKey(s.ToString()) where !keptOneAlready | _whiteList[s.ToString()] select s) { _cardsToKeep.Add(s); } return(_cardsToKeep); }