public PlayerHistory(long playerId, CClass enemyClass, DateTime date, List <string> cards) { this.PlayerId = playerId; this.EnemyClass = enemyClass; this.Date = date; this.Cards = cards; }
public override List <Card> HandleMulligan(List <Card> Choices, CClass opponentClass, CClass ownClass) { // Don't delete this _deckData = null; _playerHistories = null; _messageReceived = new AutoResetEvent(false); // For testing (replace this and everything below with your stuff) var deckData = GetEnemyDeckDataForClass(opponentClass); return(Choices); }
private List <PlayerHistory> GetOpponentHistoryWithClass(CClass heroClass) { if (_playerHistories != null) { return(_playerHistories.OrderByDescending(h => h.Date).ToList()); } _playerHistories = new List <PlayerHistory>(); SharedDataMgr.QueryRows(null, "OpponentDeckSaver", r => r["OpponentId"] == Bot.GetCurrentOpponentId().ToString() && r["EnemyHero"] == heroClass.ToString()); _messageReceived.WaitOne(3000); return(_playerHistories.OrderByDescending(h => h.Date).ToList()); }
/// <summary> /// Gets the opponents DeckArchtype based on a calculated guess. /// </summary> /// <param name="opponentClass"></param> /// <returns></returns> private DeckData GetEnemyDeckDataForClass(CClass opponentClass) { if (_deckData == null) { var playerHistory = GetOpponentHistoryWithClass(opponentClass).FirstOrDefault(); if (playerHistory != null) { _deckData = new DeckData { Cards = playerHistory.Cards }; switch (opponentClass) { case CClass.WARRIOR: { // Temporary for testing if (_deckData.Cards.Any(c => c == "BRM_019" || // Patron c == "EX1_392" || // Battle rage c == "EX1_084")) // Warsong Commander { _deckData.SubType = SubType.PatronWarrior; _deckData.ArchType = DeckArchtype.Combo; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechWarrior; _deckData.ArchType = DeckArchtype.Aggro; } else if (_deckData.Cards.Any(c => c == "AT_071" || // Alexstrasza's Champion c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonWarrior; _deckData.ArchType = DeckArchtype.Midrange; } else { // Else it's most likely Control Warrior _deckData.SubType = SubType.ControlWarrior; _deckData.ArchType = DeckArchtype.Control; } break; } case CClass.ROGUE: { if (_deckData.Cards.Any(c => c == "GVG_022")) // Tinker's Sharpsword Oil { _deckData.SubType = SubType.OilRogue; _deckData.ArchType = DeckArchtype.Combo; // Combo? } // Else we don't know, not that many rogues around these days break; } case CClass.PALADIN: { if (_deckData.Cards.Any(c => c == "AT_079")) // Mysterious Challenger { _deckData.SubType = SubType.SecretPaladin; _deckData.ArchType = DeckArchtype.Aggro; } // Need more here break; } case CClass.DRUID: { if (_deckData.Cards.Any(c => c == "NEW1_026" || // Violet Teacher c == "EX1_160")) // Power of the Wild { _deckData.SubType = SubType.TokenDruid; _deckData.ArchType = DeckArchtype.Combo; } else if (_deckData.Cards.Any(c => c == "EX1_178")) // Ancient of War { _deckData.SubType = SubType.RampDruid; _deckData.ArchType = DeckArchtype.Control; } else { // Else it's most likely Mid Range Druid _deckData.SubType = SubType.MidRangeDruid; _deckData.ArchType = DeckArchtype.Midrange; } break; } case CClass.PRIEST: { if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_004" || // Twilight Whelp c == "AT_116" || // Wyrmrest Agent c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonPriest; _deckData.ArchType = DeckArchtype.Tempo; } else { // Else it is most likely Control priest _deckData.SubType = SubType.ControlPriest; _deckData.ArchType = DeckArchtype.Control; } break; } case CClass.MAGE: { if (_deckData.Cards.Any(c => c == "GVG_005" || // Echo of Medivh c == "EX1_620")) // Molten Giant { _deckData.SubType = SubType.EchoMage; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_003" || // Unstable Portal c == "BRM_002")) // Flame Walker { _deckData.SubType = SubType.TempoMage; _deckData.ArchType = DeckArchtype.Tempo; } else if (_deckData.Cards.Any(c => c == "EX1_295")) // Ice block { _deckData.SubType = SubType.FreezeMage; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechMage; _deckData.ArchType = DeckArchtype.Aggro; } break; } case CClass.WARLOCK: { if (_deckData.Cards.Any(c => (c == "GVG_021" || // Mal'Ganis OR c == "FP1_022") && // Void Caller With one the following: (c == "EX1_043" || // Twilight Drake c == "EX1_620" || // Molten Giant c == "EX1_105"))) // Mountain Giant { _deckData.SubType = SubType.DemonHandlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonHandlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "EX1_043" || // Twilight Drake c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.Handlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_021" || // Mal'Ganis c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.DemonZooWarlock; _deckData.ArchType = DeckArchtype.Aggro; } else { // Else it's very likely to be zoolock _deckData.SubType = SubType.Zoolock; _deckData.ArchType = DeckArchtype.Aggro; } break; } case CClass.HUNTER: { if (_deckData.Cards.Any(c => c == "GVG_043" || // Glaivezooka c == "CS2_188" || // Abusive Sergeant c == "EX1_089" || // Arcane Golem c == "EX1_029")) // Leper Gnome { _deckData.SubType = SubType.FaceHunter; _deckData.ArchType = DeckArchtype.Aggro; } if (_deckData.Cards.Any(c => c == "EX1_534" || // Savannah Highmane c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.MidRangeHunter; _deckData.ArchType = DeckArchtype.Midrange; } break; } case CClass.SHAMAN: { if (_deckData.Cards.Any(c => c == "AT_046" || // Tuskarr Totemic c == "AT_049")) // //Thunder Bluff Valiant { _deckData.SubType = SubType.TotemShaman; _deckData.ArchType = DeckArchtype.Midrange; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechShaman; _deckData.ArchType = DeckArchtype.Aggro; } if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonShaman; _deckData.ArchType = DeckArchtype.Midrange; } else { // It's a random Control shaman _deckData.SubType = SubType.ControlShaman; _deckData.ArchType = DeckArchtype.Control; } break; } } } // If it's still null, it's unknown if (_deckData == null) { _deckData = new DeckData { ArchType = DeckArchtype.Unknown, SubType = SubType.Unknown, Cards = new List <string>() }; } else { // Save stats to database SharedDataMgr.AddRow("OpponentDeckHits", new string[] { Bot.GetCurrentOpponentId().ToString(CultureInfo.InvariantCulture), opponentClass.ToString(), DateTime.Now.ToString("g"), string.Join(",", _deckData.Cards), _deckData.ArchType.ToString(), _deckData.SubType.ToString() }); } } Bot.Log("[OpponentDeck] SubType: " + _deckData.SubType); Bot.Log("[OpponentDeck] Archtype: " + _deckData.ArchType); Bot.Log("[OpponentDeck] DeckList: " + string.Join(", ", _deckData.Cards)); return(_deckData); }
private void LoadOldBlackListEntries(CClass opponentClass, CClass myClass) { #region rawBlacklist if (opponentClass != CClass.PALADIN && opponentClass != CClass.HUNTER) { blackList.Add("EX1_007");//Acolyte of Pain } blackList.Add("FP1_025");//Reincarnate blackList.Add("CS2_038");//Ancestral Spirit blackList.Add("EX1_349");//Divine Favor blackList.Add("CS2_023");//Arcane Intellect blackList.Add("CS2_011");//Savage roar blackList.Add("EX1_622");//Shadow Word Death blackList.Add("EX1_625");//Shadow Form blackList.Add("DS1_233");//Mind Blast blackList.Add("CS2_108");//Execute blackList.Add("EX1_391");//Slam blackList.Add("EX1_005");//BGH blackList.Add("CS2_007");//Healing Touch blackList.Add("EX1_246");//Hex blackList.Add("EX1_575");//Mana Tide Totem blackList.Add("EX1_539");//Kill Command blackList.Add("CS2_203");//Ironbeak Owl blackList.Add("EX1_294");//Mirror entity if (opponentClass != CClass.WARLOCK) blackList.Add("EX1_238");//Lightning Bolt blackList.Add("EX1_565");//Flametongue Totem #endregion rawBlacklist }
public override List<Card> HandleMulligan(List<Card> Choices, CClass opponentClass, CClass ownClass) { int MaxManaCost = ValueReader.MaxManaCost; if ((ownClass == CClass.HUNTER || ownClass == CClass.WARLOCK) && SettingsManager.BotMode != SettingsManager.Mode.Arena && SettingsManager.BotMode != SettingsManager.Mode.ArenaAuto) { MaxManaCost = ValueReader.MaxManaCostWarlockAndHunter; } #region ListManaging LoadOldBlackListEntries(opponentClass, ownClass); if (ValueReader.AddMillhouseToBlackList) blackList.Add("NEW1_029");//Millhouse blackList.Add("CS2_118");//Magma Rager blackList.Add("EX1_132"); //Eye for an Eye blackList.Add("CS2_231"); //Wisp switch (ownClass) { case CClass.DRUID: blackList.Add("CS2_012");//Swipe if (Choices.Count(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION) >= 2) blackList.Add("CS2_011");//Savage Roar whiteList.Add("EX1_169");//Innervate whiteList.Add("EX1_154");//Wrath if (Choices.Any(x => x.Name == "EX1_169" || x.Name == "CS2_013")) { whiteList.Add("FP1_005");//Shade of Naxxramas Druid.rampStructure = true; } if (Druid.rampStructure) { whiteList.Add("EX1_085");//Mind Control Tech whiteList.Add("GVG_096");//Piloted Shredder } whiteList.Add("CS2_013");//Wild Growth if (Choices.Any(x => CardProperties.HasEffect(x, "Taunt") && x.Name != "FP1_028" && x.Cost <= 3)) { whiteList.Add("FP1_028");//Undertaker whiteList.Add(Choices.FirstOrDefault(x => CardProperties.HasEffect(x, "Deathrattle") && x.Name != "FP1_028" && x.Cost <= 3).Name); } if (Choices.Count(x => CardProperties.HasEffect(x, "Deathrattle")) < Choices.Count(x => x.Name != whiteList[0])) whiteList.Add("CS2_009");//Mark of the Wild whiteList.Add("CS2_005");//Claw if (Choices.Any(x => new BoardCard(x).ResultingBoardCard.Type == CType.WEAPON || x.Name == "CS2_005")) whiteList.Add("EX1_578");//Savagery else blackList.Add("EX1_578");//Savagery break; case CClass.HUNTER: whiteList.Add("NEW1_031");//Animal Companion whiteList.Add("EX1_617");//Deadly Shot if (Choices.Count(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION && !blackList.Contains(x.Name)) >= 2) whiteList.Add("EX1_611");//Freezing Trap else blackList.Add("EX1_611");//Freezing Trap if (!Choices.Any(x => CardProperties.HasEffect(x, "Stealth"))) whiteList.Add("EX1_544");//Flare else blackList.Add("EX1_544");//Flare if (Choices.Count(x => CardProperties.HasEffect(x, "Deathrattle")) >= 2) whiteList.Add("GVG_026");//Feign Death else blackList.Add("GVG_026");//Feign Death if (Choices.Count(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION && new BoardCard(x).ResultingBoardCard.Race == SmartBot.Plugins.API.Card.CRace.BEAST && !blackList.Contains(x.Name)) >= 3) whiteList.Add("DS1_175");//Timber Wolf else blackList.Add("DS1_175");//Timber Wolf whiteList.Add("GVG_043");//Glaivezooka whiteList.Add("GVG_087");//Steamwheedle Sniper whiteList.Add("BRM_013");//Quick Shot whiteList.Add("FP1_011");//Webspinner whiteList.Add("DS1_184");//Tracking whiteList.Add("DS1_185");//Arcane Shot if (Choices.Count > 3) whiteList.Add("EX1_014");//Mukla break; case CClass.MAGE: whiteList.Add("EX1_608");//Sorcerer's Apprentice whiteList.Add("GVG_002");//Snowchugger whiteList.Add("CS2_024");//Frostbolt whiteList.Add("GVG_001");//Flamecannon whiteList.Add("CS2_mirror");//Mirror Image whiteList.Add("NEW1_012");//Mana Wyrm whiteList.Add("EX1_277");//Arcane Missiles break; case CClass.PALADIN: whiteList.Add("EX1_366");//Sword of Justice if (opponentClass == CClass.DRUID || opponentClass == CClass.WARLOCK) whiteList.Add("GVG_101");//Scarlet Purifier whiteList.Add("GVG_061");//Muster for Battle whiteList.Add("EX1_382");//Aldor Peacekeeper whiteList.Add("GVG_058");//Shielded Minibot whiteList.Add("EX1_362");//Argent Protector whiteList.Add("EX1_130");//Noble Sacrifice whiteList.Add("CS2_091");//Light's Justice whiteList.Add("EX1_363");//Blessing of Wisdom whiteList.Add("CS2_087");//Blessing of Might whiteList.Add("FP1_020");//Avenges break; case CClass.PRIEST: whiteList.Add("EX1_339");//Thoughtsteal whiteList.Add("GVG_072");//Shadowboxer whiteList.Add("CS2_234");//Shadow Word: Pain if (Choices.Any(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION && x.Cost <= 3 && !blackList.Contains(x.Name))) whiteList.Add("CS2_236");//Divine Spirit else blackList.Add("CS2_236");//Divine Spirit whiteList.Add("GVG_009");//Shadowbomber whiteList.Add("CS2_004");//Power Word: Shield whiteList.Add("CS2_235");//Northshire Cleric whiteList.Add("EX1_332");//Silence whiteList.Add("CS1_130");//Holy Smite whiteList.Add("CS1_129");//Inner Fire whiteList.Add("CS2_181");//Injured Blademaster if (Choices.Any(x => x.Name == "CS2_181")) whiteList.Add("EX1_621"); // Circle of Healing else blackList.Add("EX1_621"); if (Choices.Count > 3) { if (Choices.Any(x => x.Name == "CS2_235"))//Northshire Cleric whiteList.Add("CS2_004");//Power Word: Shield if (Choices.Any(x => x.Name == "CS2_181"))//Injured Blademaster whiteList.Add("EX1_621");//Circle of Healing } if (opponentClass == CClass.WARRIOR || opponentClass == CClass.PALADIN) whiteList.Add("EX1_588"); else blackList.Add("EX1_588"); if (Choices.Count(c => c.Name == "FP1_001" || c.Name == "CS2_235" || c.Name == "GVG_081") > 1) { whiteList.Add("CS2_004");//Power Word: Shield whiteList.Add("GVG_010");//Velen's Chosen whiteList.Add("FP1_009");//Deathlord } break; case CClass.ROGUE: if (Choices.Any(x => x.Cost <= 1 && (new BoardCard(x).ResultingBoardCard.Type == CType.SPELL || new BoardCard(x).ResultingBoardCard.Type == CType.WEAPON)) && !Choices.Any(x => x.Name == "EX1_131")) whiteList.Add("EX1_134"); //SI:7-Agent whiteList.Add("EX1_129"); //Dolchfächer whiteList.Add("EX1_126"); //Verrat if (Choices.Any(x => x.Cost <= 1 && (new BoardCard(x).ResultingBoardCard.Type == CType.SPELL || new BoardCard(x).ResultingBoardCard.Type == CType.WEAPON))) whiteList.Add("EX1_131"); //Rädelsführer der Defias whiteList.Add("GVG_023"); //Goblinbarbier-o-Mat whiteList.Add("EX1_522"); //Geduldiger Attentäter whiteList.Add("EX1_124"); //Ausweiden whiteList.Add("CS2_074"); //Tödliches Gift whiteList.Add("CS2_073"); //Kaltblütigkeit whiteList.Add("CS2_072"); //Meucheln whiteList.Add("CS2_075"); //Finsterer Stoß whiteList.Add("EX1_145"); //Vorbereitung break; case CClass.SHAMAN: whiteList.Add("EX1_248"); //Wildgeist whiteList.Add("EX1_575"); //Manafluttotem whiteList.Add("EX1_259"); //Gewittersturm whiteList.Add("EX1_258"); //Entfesselter Elementar whiteList.Add("GVG_037"); //Wirbelnder Zapp-o-Mat whiteList.Add("CS2_039"); //Windzorn whiteList.Add("EX1_247");//Stormforged Axe whiteList.Add("FP1_025");//Reincarnate whiteList.Add("EX1_565");//Flametongue Totem whiteList.Add("GVG_038");//Crackle whiteList.Add("CS2_045");//Rockbiter Weapon whiteList.Add("EX1_238");//Lightning Bolt whiteList.Add("CS2_037");//Frost Shock whiteList.Add("EX1_251");//Forked Lightning whiteList.Add("EX1_245");//Earth Shock whiteList.Add("EX1_243");//Dust Devil whiteList.Add("EX1_244");//Totemic Might whiteList.Add("CS2_041");//Ancestral Healing break; case CClass.WARLOCK: whiteList.Add("BRM_005");//Demonwrath whiteList.Add("CS2_065");//Voidwalker whiteList.Add("EX1_306");//Succubus whiteList.Add("EX1_596");//Demonfire whiteList.Add("GVG_015");//Darkbomb whiteList.Add("EX1_308");//Soulfire whiteList.Add("EX1_302");//Mortal Coil whiteList.Add("EX1_319");//Flame Imp whiteList.Add("CS2_059");//Blood Imp break; case CClass.WARRIOR: if (Choices.Any(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION)) whiteList.Add("EX1_402");//Armorsmith if (Choices.Any(x => new BoardCard(x).ResultingBoardCard.Type == CType.MINION && new BoardCard(x).ResultingBoardCard.Health > 1)) whiteList.Add("CS2_104");//Rampage if (Choices.Any(x => x.Name == "EX1_007" || x.Name == "EX1_393")) whiteList.Add("EX1_607"); //Inner Rage else blackList.Add("EX1_607"); if (Choices.Any(x => x.Name == "EX1_607")) whiteList.Add("EX1_007"); //Acolyte whiteList.Add("EX1_604");//Frothing Berserker { float averageMana = 0; foreach (var card in Choices) averageMana += card.Cost; averageMana = averageMana / Choices.Count; if (averageMana < 4f) whiteList.Add("GVG_050");//Bouncing Blade } switch (opponentClass) { case CClass.WARLOCK: whiteList.Add("EX1_402");//Armorsmith whiteList.Add("FP1_021");//Death's Bite break; case CClass.SHAMAN: whiteList.Add("EX1_402");//Armorsmith whiteList.Add("FP1_021");//Death's Bite break; case CClass.PRIEST: whiteList.Add("EX1_402");//Armorsmith whiteList.Add("EX1_606");//Shield Block whiteList.Add("EX1_410");//Shield Slam whiteList.Add("EX1_007");//Acolyte of Pain whiteList.Add("FP1_021");//Death's Bite break; case CClass.ROGUE: whiteList.Add("EX1_606");//Shield Block whiteList.Add("EX1_410");//Shield Slam whiteList.Add("FP1_021");//Death's Bite break; } whiteList.Add("EX1_391");//Slam whiteList.Add("CS2_105");//Heroic Strike whiteList.Add("CS2_106");//Fiery War Axe whiteList.Add("EX1_603");//Cruel Taskmaster whiteList.Add("NEW1_036");//Commanding Shout whiteList.Add("CS2_114");//Cleave whiteList.Add("GVG_051");//Warbot if (Choices.Any(x => new BoardCard(x).ResultingBoardCard.Type == CType.WEAPON)) whiteList.Add("EX1_409");//Upgrade! whiteList.Add("EX1_410");//Shield Slam whiteList.Add("CS2_108");//Execute break; } switch (opponentClass) { case CClass.DRUID: whiteList.Add("EX1_591");//Auchenai Priest whiteList.Add("EX1_339");//Thoughtsteal whiteList.Add("EX1_621");//Circle of Healing break; case CClass.WARRIOR: whiteList.Add("EX1_591");//Auchenai Priest whiteList.Add("EX1_339");//Thoughtsteal whiteList.Add("EX1_621");//Circle of Healing whiteList.Add("CS2_179");//Sen'jin Shieldmasta break; case CClass.ROGUE: whiteList.Add("EX1_591");//Auchenai Priest whiteList.Add("EX1_621");//Circle of Healing whiteList.Add("EX1_339");//Thoughtsteal whiteList.Add("FP1_030");//Loatheb whiteList.Add("CS2_179");//Sen'jin Shieldmasta break; case CClass.PRIEST: whiteList.Add("EX1_591");//Auchenai Priest whiteList.Add("EX1_339");//Thoughtsteal whiteList.Add("EX1_621");//Circle of Healing whiteList.Add("FP1_030");//Loatheb break; } #endregion ListManaging CalculateMulligan(Choices, MaxManaCost, ownClass); return chosenCards; }
private void CalculateMulligan(List<Card> Choices, int MaxManaCost, CClass ownClass) { #region TwinManaging for (int i = 0; i < Choices.Count; i++) { for (int j = 0; j < Choices.Count; j++) { if (i != j && Choices[i].Name.Equals(Choices[j].Name)) { if (Choices[i].Cost < ValueReader.DontAllowTwinsIfManaCostAtLeast && ValueReader.AllowTwins) continue; else if (!ValueReader.AllowTwins || Choices[i].Cost >= ValueReader.DontAllowTwinsIfManaCostAtLeast) { chosenCards.Add(Choices[i]); blackList.Add(Choices[i].Name); } } } } #endregion TwinManaging foreach (var card in Choices.Where(x => !blackList.Contains(x.Name))) { if (card.Name == "GAME_005") //Coin { chosenCards.Add(card); continue; } if (whiteList.Contains(card.Name)) chosenCards.Add(card); else if (!ClassCards.IsClassCard(card) && card.Cost <= MaxManaCost) ManageNeutralMinion(card, MaxManaCost, Choices); } }
public override List<Card> HandleMulligan(List<Card> Choices, CClass opponentClass, CClass ownClass) { // Don't delete this _deckData = null; _playerHistories = null; _messageReceived = new AutoResetEvent(false); // For testing (replace this and everything below with your stuff) var deckData = GetEnemyDeckDataForClass(opponentClass); return Choices; }
public PlayerHistory(long playerId, CClass enemyClass, DateTime date, List<string> cards) { this.PlayerId = playerId; this.EnemyClass = enemyClass; this.Date = date; this.Cards = cards; }
private List<PlayerHistory> GetOpponentHistoryWithClass(CClass heroClass) { if (_playerHistories != null) return _playerHistories.OrderByDescending(h => h.Date).ToList(); _playerHistories = new List<PlayerHistory>(); SharedDataMgr.QueryRows(null, "OpponentDeckSaver", r => r["OpponentId"] == Bot.GetCurrentOpponentId().ToString() && r["EnemyHero"] == heroClass.ToString()); _messageReceived.WaitOne(3000); return _playerHistories.OrderByDescending(h => h.Date).ToList(); }
/// <summary> /// Gets the opponents DeckArchtype based on a calculated guess. /// </summary> /// <param name="opponentClass"></param> /// <returns></returns> private DeckData GetEnemyDeckDataForClass(CClass opponentClass) { if (_deckData == null) { var playerHistory = GetOpponentHistoryWithClass(opponentClass).FirstOrDefault(); if (playerHistory != null) { _deckData = new DeckData { Cards = playerHistory.Cards }; switch (opponentClass) { case CClass.WARRIOR: { // Temporary for testing if (_deckData.Cards.Any(c => c == "BRM_019" || // Patron c == "EX1_392" || // Battle rage c == "EX1_084")) // Warsong Commander { _deckData.SubType = SubType.PatronWarrior; _deckData.ArchType = DeckArchtype.Combo; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechWarrior; _deckData.ArchType = DeckArchtype.Aggro; } else if (_deckData.Cards.Any(c => c == "AT_071" || // Alexstrasza's Champion c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonWarrior; _deckData.ArchType = DeckArchtype.Midrange; } else { // Else it's most likely Control Warrior _deckData.SubType = SubType.ControlWarrior; _deckData.ArchType = DeckArchtype.Control; } break; } case CClass.ROGUE: { if (_deckData.Cards.Any(c => c == "GVG_022")) // Tinker's Sharpsword Oil { _deckData.SubType = SubType.OilRogue; _deckData.ArchType = DeckArchtype.Combo; // Combo? } // Else we don't know, not that many rogues around these days break; } case CClass.PALADIN: { if (_deckData.Cards.Any(c => c == "AT_079")) // Mysterious Challenger { _deckData.SubType = SubType.SecretPaladin; _deckData.ArchType = DeckArchtype.Aggro; } // Need more here break; } case CClass.DRUID: { if (_deckData.Cards.Any(c => c == "NEW1_026" || // Violet Teacher c == "EX1_160")) // Power of the Wild { _deckData.SubType = SubType.TokenDruid; _deckData.ArchType = DeckArchtype.Combo; } else if (_deckData.Cards.Any(c => c == "EX1_178")) // Ancient of War { _deckData.SubType = SubType.RampDruid; _deckData.ArchType = DeckArchtype.Control; } else { // Else it's most likely Mid Range Druid _deckData.SubType = SubType.MidRangeDruid; _deckData.ArchType = DeckArchtype.Midrange; } break; } case CClass.PRIEST: { if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_004" || // Twilight Whelp c == "AT_116" || // Wyrmrest Agent c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonPriest; _deckData.ArchType = DeckArchtype.Tempo; } else { // Else it is most likely Control priest _deckData.SubType = SubType.ControlPriest; _deckData.ArchType = DeckArchtype.Control; } break; } case CClass.MAGE: { if (_deckData.Cards.Any(c => c == "GVG_005" || // Echo of Medivh c == "EX1_620")) // Molten Giant { _deckData.SubType = SubType.EchoMage; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_003" || // Unstable Portal c == "BRM_002")) // Flame Walker { _deckData.SubType = SubType.TempoMage; _deckData.ArchType = DeckArchtype.Tempo; } else if (_deckData.Cards.Any(c => c == "EX1_295")) // Ice block { _deckData.SubType = SubType.FreezeMage; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechMage; _deckData.ArchType = DeckArchtype.Aggro; } break; } case CClass.WARLOCK: { if (_deckData.Cards.Any(c => (c == "GVG_021" ||// Mal'Ganis OR c == "FP1_022") && // Void Caller With one the following: (c == "EX1_043" || // Twilight Drake c == "EX1_620" || // Molten Giant c == "EX1_105"))) // Mountain Giant { _deckData.SubType = SubType.DemonHandlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonHandlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "EX1_043" || // Twilight Drake c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.Handlock; _deckData.ArchType = DeckArchtype.Control; } else if (_deckData.Cards.Any(c => c == "GVG_021" || // Mal'Ganis c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.DemonZooWarlock; _deckData.ArchType = DeckArchtype.Aggro; } else { // Else it's very likely to be zoolock _deckData.SubType = SubType.Zoolock; _deckData.ArchType = DeckArchtype.Aggro; } break; } case CClass.HUNTER: { if (_deckData.Cards.Any(c => c == "GVG_043" || // Glaivezooka c == "CS2_188" || // Abusive Sergeant c == "EX1_089" || // Arcane Golem c == "EX1_029")) // Leper Gnome { _deckData.SubType = SubType.FaceHunter; _deckData.ArchType = DeckArchtype.Aggro; } if (_deckData.Cards.Any(c => c == "EX1_534" || // Savannah Highmane c == "EX1_620" || // Molten Giant c == "EX1_105")) // Mountain Giant { _deckData.SubType = SubType.MidRangeHunter; _deckData.ArchType = DeckArchtype.Midrange; } break; } case CClass.SHAMAN: { if (_deckData.Cards.Any(c => c == "AT_046" || // Tuskarr Totemic c == "AT_049")) // //Thunder Bluff Valiant { _deckData.SubType = SubType.TotemShaman; _deckData.ArchType = DeckArchtype.Midrange; } else if (_deckData.Cards.Any(c => c == "GVG_082" || // Clockwork Gnome c == "GVG_013" || // Cogmaster c == "GVG_085" || // Annoy-o-Tron c == "GVG_006")) // Mechwarper { _deckData.SubType = SubType.MechShaman; _deckData.ArchType = DeckArchtype.Aggro; } if (_deckData.Cards.Any(c => c == "AT_017" || // Twilight Guardian c == "BRM_033" || // Blackwing Technician c == "BRM_034")) // Blackwing Corruptor { _deckData.SubType = SubType.DragonShaman; _deckData.ArchType = DeckArchtype.Midrange; } else { // It's a random Control shaman _deckData.SubType = SubType.ControlShaman; _deckData.ArchType = DeckArchtype.Control; } break; } } } // If it's still null, it's unknown if (_deckData == null) { _deckData = new DeckData { ArchType = DeckArchtype.Unknown, SubType = SubType.Unknown, Cards = new List<string>() }; } else { // Save stats to database SharedDataMgr.AddRow("OpponentDeckHits", new string[] { Bot.GetCurrentOpponentId().ToString(CultureInfo.InvariantCulture), opponentClass.ToString(), DateTime.Now.ToString("g"), string.Join(",", _deckData.Cards), _deckData.ArchType.ToString(), _deckData.SubType.ToString() }); } } Bot.Log("[OpponentDeck] SubType: " + _deckData.SubType); Bot.Log("[OpponentDeck] Archtype: " + _deckData.ArchType); Bot.Log("[OpponentDeck] DeckList: " + string.Join(", ", _deckData.Cards)); return _deckData; }