I believe that the current way the opening hand and replacing/keeping the cards is flawed. For one, I believe that the question you should ask yourself when looking at the hand you get at the start of the game is not "Which cards I want to discard?", but "Which cards I want to keep?". And here is why. Imagine you are playing a warlock. Let's also say that, you would prefer to always keep Mal'Ganis, and if you are facing a hunter, then you'd also like to keep Defender of Argus and Nerubian Egg. Of course, you'd prefer to keep any 1-3 cost minions. The way HB currently handles this is not with "I WANT TO KEEP XYZ", but "I WANT TO DISCARD XYZ" So, let's assume your opening hand consists of Flame Imp, Mal'Ganis and Defender of Argus. The rules, as they are, could be written like this (per instructions in DefaultRoutine.cs): _mulliganRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.WARLOCK", "card.Entity.Cost >= 4 and card.Entity.Id != "<Mal'Ganis ID>"")); _mulliganRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.WARLOCK and mulliganData.OpponentClass == TAG_CLASS.HUNTER", "card.Entity.Id != "<Defender of Argus ID>"")); The way HB handles this can be described as following: Code: initially, mark all cards in hand to be kept for each card in hand do the following: for each mulligan rule, check if it applies if it applies, check for card condition if card condition evaluates as true, mark card to be discarded So, let's see what would happen if we had Flame Imp, Mal'Ganis and Defender of Argus in our hand. With the rules above, we want to keep all 3 of them: Flame Imp: Since Flame Imp's cost is 1, the 1st mulligan card condition rule evaluates as false Since Flame Imp's ID is not Defender of argus, 2nd mulligan card condition evaluates as false We are done with Flame Imp and his Mulligan Status remains False. Mal'Ganis: Mal'Ganis' cost is >= 4, but his ID is the same as Mal'Ganis' ID, so 1st evaluation is (true && false) = false Mal'Ganis' ID is different from Defender of Argus ID, so that evaluation is true, and Mal'Ganis is being marked for replacement. Defender of Argus Cost is >=4 and it is not Mal'Ganis, so the 1st evaluation is (true && true = true), and Defender of Argus is being marked for replacement. So, even if we wanted to keep both Mal'Ganis and Defender of Argus, with the following system and rule advice, it fails. What is propose goes something like this: Code: Initially, mark all cards to be discarded. for each card for each card-keeping rule, check if it applies if card keeping rule applies mark card for keeping and stop executing other rules and go to the next card So, let's create some rules with this system: _cardKeepingRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.WARLOCK", "card.Entity.Cost < 4 or card.Entity.Id == "<Mal'Ganis ID>"")); _cardKeepingRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.WARLOCK and mulliganData.OpponentClass == TAG_CLASS.HUNTER", "card.Entity.Id == "<Defender of Argus ID>"")); Let's see how the execution goes: Flame Imp: 1st rule - evaluates true, since the card cost is < 4. It is kept, and we move to the next card. Mal'Ganis: 1st rule - evaluates true, since the card IS Mal'Ganis. It is kept, and we move to the next card. Defender of Argus: 1st rule - evaluates false, since it's not a 1-3 minion nor is it Mal'Ganis. We move to 2nd rule. 2nd rule - evaluates true, since the card IS Defender of Argus. It is kept, and we move to the next card. Since there are no more cards, this phase is over and we've successfully kept cards we wanted. In fact, I think separate card keeping and card discarding rule resolving should be implemented, so that both scenarios are simple to define. Here's a snippet of what I mean: https://ideone.com/FaH0Sa
I second this. This is critical for building decks around legendary cards and thus improving the quality of the bot in itself. Given the small amount of changing that *should* need to be done, hopefully pushedx could implement this very soon. If they even look at this section.