Merge branch 'master' into 'master'

Improved London Mulligan AI

See merge request core-developers/forge!1844
This commit is contained in:
Michael Kamensky
2019-06-12 08:01:41 +00:00
2 changed files with 38 additions and 5 deletions

View File

@@ -552,11 +552,45 @@ public class PlayerControllerAi extends PlayerController {
@Override
public CardCollectionView londonMulliganReturnCards(final Player mulliganingPlayer, int cardsToReturn) {
// TODO This is awful. Don't do this.
// TODO This is better than it was before, but still suboptimal (but fast).
// Maybe score a bunch of hands based on projected hand size and return the "duds"
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand));
CardCollection landsInHand = CardLists.filter(hand, Presets.LANDS);
int numLandsInHand = landsInHand.size();
int numLandsDesired = (mulliganingPlayer.getStartingHandSize() - cardsToReturn) / 2;
return CardCollection.getView(hand.subList(0, cardsToReturn));
CardCollection toReturn = new CardCollection();
for (int i = 0; i < cardsToReturn; i++) {
// If we're flooding with lands, get rid of the worst land we have
if (numLandsInHand > 0 && numLandsInHand > numLandsDesired) {
CardCollection producingLands = CardLists.filter(landsInHand, Presets.LANDS_PRODUCING_MANA);
CardCollection nonProducingLands = CardLists.filter(landsInHand, Predicates.not(Presets.LANDS_PRODUCING_MANA));
Card worstLand = nonProducingLands.isEmpty() ? ComputerUtilCard.getWorstLand(producingLands)
: ComputerUtilCard.getWorstLand(nonProducingLands);
toReturn.add(worstLand);
continue;
}
// See if we'd scry something to the bottom in this situation. If we want to, probably get rid of it.
CardCollection scryBottom = new CardCollection();
for (Card c : hand) {
// Lands are evaluated separately above, factoring in the number of cards to be returned to the library
if (!c.isLand() && !toReturn.contains(c) && !willPutCardOnTop(c)) {
scryBottom.add(c);
}
}
if (!scryBottom.isEmpty()) {
CardLists.sortByCmcDesc(scryBottom);
toReturn.add(scryBottom.getFirst()); // assume the max CMC one is worse since we're not guaranteed to have lands for it
continue;
}
// If we don't want to scry anything to the bottom, remove the worst card that we have in order to satisfy
// the requirement
toReturn.add(ComputerUtilCard.getWorstAI(hand));
}
return CardCollection.getView(toReturn);
}
@Override

View File

@@ -1,8 +1,7 @@
Name:Goatnap
ManaCost:2 R
Types:Sorcery
A:SP$ GainControl | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | Untap$ True | LoseControl$ EOT | SubAbility$ DBPumpHaste | SpellDescription$ Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a, it also gets +3/+0 until end of turn.
SVar:DBPumpHaste:DB$ Pump | Defined$ Targeted | KW$ Haste | SubAbility$ DBPump
A:SP$ GainControl | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | Untap$ True | AddKWs$ Haste | LoseControl$ EOT | SubAbility$ DBPump | SpellDescription$ Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a, it also gets +3/+0 until end of turn.
SVar:DBPump:DB$ Pump | Defined$ Targeted | NumAtt$ 3 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | References$ X
SVar:X:Targeted$Valid Goat
Oracle:Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a goat, it also gets +3/+0 until end of turn.