Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions forge-ai/src/main/java/forge/ai/SpecialCardAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -1198,27 +1198,13 @@ public static Card considerCardToGet(final Player ai, final SpellAbility sa) {
public static class MairsilThePretender {
// Scan the fetch list for a card with at least one activated ability.
// TODO: can be improved to a full consider(sa, ai) logic which would scan the graveyard first and hand last
public static Card considerCardFromList(final CardCollection fetchList) {
for (Card c : CardLists.filter(fetchList, CardPredicates.ARTIFACTS.or(CardPredicates.CREATURES))) {
for (SpellAbility ab : c.getSpellAbilities()) {
if (ab.isActivatedAbility()) {
Player controller = c.getController();
boolean wasCaged = false;
for (Card caged : CardLists.filter(controller.getCardsIn(ZoneType.Exile),
CardPredicates.hasCounter(CounterEnumType.CAGE))) {
if (c.getName().equals(caged.getName())) {
wasCaged = true;
break;
}
}

if (!wasCaged) {
return c;
}
}
}
}
return null;
public static Card considerCardFromList(final CardCollection fetchList, SpellAbility sa) {
CardCollectionView caged = CardLists.filter(sa.getActivatingPlayer().getCardsIn(ZoneType.Exile),
CardPredicates.hasCounter(CounterType.getType("CAGE")));
return fetchList.stream().filter(CardPredicates.ARTIFACTS.or(CardPredicates.CREATURES))
.filter(c -> c.getSpellAbilities().stream().anyMatch(SpellAbility::isActivatedAbility))
.filter(c -> caged.stream().noneMatch(CardPredicates.sharesNameWith(c)))
.findFirst().orElse(null);
}
}

Expand Down Expand Up @@ -1827,7 +1813,7 @@ public static AiAbilityDecision consider(final Player ai, final SpellAbility sa)

AiController aic = ((PlayerControllerAi) ai.getController()).getAi();
int lifeInDanger = aic.getIntProperty(AiProps.AI_IN_DANGER_THRESHOLD);
int numCtrs = sa.getHostCard().getCounters(CounterEnumType.BURDEN);
int numCtrs = sa.getHostCard().getCounters(CounterType.getType("BURDEN"));

if (ai.getLife() > numCtrs + 1 && ai.getLife() > lifeInDanger
&& ai.getMaxHandSize() >= ai.getCardsIn(ZoneType.Hand).size() + numCtrs + 1) {
Expand Down
2 changes: 1 addition & 1 deletion forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ public static Card chooseCardToHiddenOriginChangeZone(ZoneType destination, List
} else if ("BestCard".equals(logic)) {
return ComputerUtilCard.getBestAI(fetchList); // generally also means the most expensive one or close to it
} else if ("Mairsil".equals(logic)) {
return SpecialCardAi.MairsilThePretender.considerCardFromList(fetchList);
return SpecialCardAi.MairsilThePretender.considerCardFromList(fetchList, sa);
} else if ("SurvivalOfTheFittest".equals(logic)) {
return SpecialCardAi.SurvivalOfTheFittest.considerCardToGet(decider, sa);
} else if ("MazesEnd".equals(logic)) {
Expand Down
10 changes: 6 additions & 4 deletions forge-ai/src/main/java/forge/ai/ability/LegendaryRuleAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import forge.ai.SpellAbilityAi;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;

Expand Down Expand Up @@ -41,21 +41,23 @@ public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options,
} else {
// AI decision making - should AI compare damage and debuffs?
}
CounterType ice = CounterType.getType("ICE");
CounterType ki = CounterType.getType("KI");

// TODO: Can this be made more generic somehow?
if (firstOption.getName().equals("Dark Depths")) {
Card best = firstOption;
for (Card c : options) {
if (c.getCounters(CounterEnumType.ICE) < best.getCounters(CounterEnumType.ICE)) {
if (c.getCounters(ice) < best.getCounters(ice)) {
best = c;
}
}
return best;
} else if (firstOption.getCounters(CounterEnumType.KI) > 0) {
} else if (firstOption.getCounters(ki) > 0) {
// Extra Rule for KI counter
Card best = firstOption;
for (Card c : options) {
if (c.getCounters(CounterEnumType.KI) > best.getCounters(CounterEnumType.KI)) {
if (c.getCounters(ki) > best.getCounters(ki)) {
best = c;
}
}
Expand Down
3 changes: 2 additions & 1 deletion forge-ai/src/main/java/forge/ai/ability/SetStateAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,9 @@ private boolean isSafeToTransformIntoLegendary(Player aiPlayer, Card source) {

final Card othercard = aiPlayer.getCardsIn(ZoneType.Battlefield, other.getName()).getFirst();

CounterType ki = CounterType.getType("KI");
// for legendary KI counter creatures
if (othercard.getCounters(CounterEnumType.KI) >= source.getCounters(CounterEnumType.KI)) {
if (othercard.getCounters(ki) >= source.getCounters(ki)) {
// if the other legendary is useless try to replace it
return ComputerUtilCard.isUselessCreature(aiPlayer, othercard);
}
Expand Down
Loading
Loading