mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
A bit more with AI for Pump + KWChoice (#1637)
* some more tweaks * PlayerControllerAi.chooseKeywordForPump refine some more * SpecialCardAi remove Gideon keyword stuff * PlayerControllerAi.chooseKeywordForPump improve further * Card.associatedWithColor and Card.canProduceColorMana checks * restore imports
This commit is contained in:
@@ -7,6 +7,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.keyword.Keyword;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -942,14 +943,68 @@ public class PlayerControllerAi extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseKeywordForPump(final List<String> options, final SpellAbility sa, final String prompt) {
|
||||
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
||||
|
||||
if (aiLogic.equals("GideonBlackblade")) {
|
||||
return SpecialCardAi.GideonBlackblade.chooseKeyword(player, sa, options);
|
||||
public String chooseKeywordForPump(final List<String> options, final SpellAbility sa, final String prompt, final Card tgtCard) {
|
||||
if (options.size() <= 1) {
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
List<String> possible = Lists.newArrayList();
|
||||
CardCollection oppUntappedCreatures = CardLists.filter(player.getOpponents().getCreaturesInPlay(), CardPredicates.Presets.UNTAPPED);
|
||||
if (tgtCard != null) {
|
||||
for (String kw : options) {
|
||||
if (tgtCard.hasKeyword(kw)) {
|
||||
continue;
|
||||
} else if ("Indestructible".equals(kw)) {
|
||||
if (oppUntappedCreatures.isEmpty()) {
|
||||
continue; // no threats on battlefield - removal still a concern perhaps?
|
||||
} else {
|
||||
possible.clear();
|
||||
possible.add(kw); // prefer Indestructible above all else
|
||||
break;
|
||||
}
|
||||
} else if ("Flying".equals(kw)) {
|
||||
if (oppUntappedCreatures.isEmpty()) {
|
||||
continue; // no need for evasion
|
||||
} else {
|
||||
boolean flyingGood = true;
|
||||
for (Card c : oppUntappedCreatures) {
|
||||
if (c.hasKeyword(Keyword.FLYING) || c.hasKeyword(Keyword.REACH)) {
|
||||
flyingGood = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flyingGood) {
|
||||
possible.clear();
|
||||
possible.add(kw); // flying is great when no one else has it
|
||||
break;
|
||||
} // even if opp has flying or reach, flying might still be useful so we won't skip it
|
||||
}
|
||||
} else if (kw.startsWith("Protection from ")) {
|
||||
//currently, keyword choice lists only include color protection
|
||||
final String fromWhat = kw.substring(16);
|
||||
boolean found = false;
|
||||
for (String color : MagicColor.Constant.ONLY_COLORS) {
|
||||
if (color.equalsIgnoreCase(fromWhat)) {
|
||||
CardCollection known = player.getOpponents().getCardsIn(ZoneType.Battlefield);
|
||||
for (final Card c : known) {
|
||||
if (c.associatedWithColor(color)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
possible.add(kw);
|
||||
}
|
||||
}
|
||||
if (!possible.isEmpty()) {
|
||||
return Aggregates.random(possible);
|
||||
} else {
|
||||
return Aggregates.random(options); // if worst comes to worst, at least do something
|
||||
}
|
||||
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -601,34 +601,6 @@ public class SpecialCardAi {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String chooseKeyword(final Player ai, final SpellAbility sa, final List<String> options) {
|
||||
// TODO: generalize and improve this so that it acts in a more reasonable way and can potentially be used for other cards too
|
||||
List<String> possible = Lists.newArrayList();
|
||||
Card tgtCard = sa.getTargetCard();
|
||||
if (tgtCard != null) {
|
||||
CardCollection oppUntappedCreatures = CardLists.filter(ai.getOpponents().getCreaturesInPlay(), CardPredicates.Presets.UNTAPPED);
|
||||
for (String kw : options) {
|
||||
if (!tgtCard.hasKeyword(kw)) {
|
||||
if ("Indestructible".equals(kw)) {
|
||||
if (oppUntappedCreatures.isEmpty()) {
|
||||
continue; // nothing to damage or kill the creature with
|
||||
} else {
|
||||
possible.clear();
|
||||
possible.add(kw); // prefer Indestructible above all else
|
||||
break;
|
||||
}
|
||||
}
|
||||
possible.add(kw); // these SAs at least don't duplicate a keyword on the card
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!possible.isEmpty()) {
|
||||
return Aggregates.random(possible);
|
||||
} else {
|
||||
return Aggregates.random(options); // if worst comes to worst, it's a PW +1 ability, so do at least something
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Goblin Polka Band
|
||||
|
||||
Reference in New Issue
Block a user