AI updates, more cards will have the isRemoval bonus to their card rating

these weren't being picked up as removal spells and now are:
* modal spells where one mode is a removal spell
* spells that do a dynamic amount of damage, such as fireball
* cards that reduce the toughness temporarily or permanently
* cards that keep a creature tapped down
* cards that exile a creature
* cards that damage creatures that are attacking or blocking
* enchantments that exile a creature when they etb
* fight cards, and one sided fight cards

the ai will now rate those types of cards higher as they are removal
This commit is contained in:
brodee 2018-10-28 00:16:14 -07:00
parent bdf3394b84
commit 4f61afa62b
6 changed files with 69 additions and 30 deletions

View file

@ -7,14 +7,25 @@ import mage.cards.Card;
import mage.constants.ColoredManaSymbol;
import mage.constants.Outcome;
import mage.target.Target;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
import org.apache.log4j.Logger;
import java.io.InputStream;
import java.util.*;
import mage.abilities.Mode;
import mage.abilities.effects.common.DamageWithPowerTargetEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.effects.common.FightTargetsEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.constants.Rarity;
import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetAttackingCreature;
import mage.target.common.TargetAttackingOrBlockingCreature;
import mage.target.common.TargetPlayerOrPlaneswalker;
/**
* Class responsible for reading ratings from resources and rating given cards.
@ -54,7 +65,6 @@ public final class RateCard {
public static int rateCard(Card card, List<ColoredManaSymbol> allowedColors) {
if (allowedColors == null && rated.containsKey(card.getName())) {
int rate = rated.get(card.getName());
// log.info(card.getName() + " rate: " + rate);
return rate;
}
int type;
@ -79,41 +89,69 @@ public final class RateCard {
}
private static int isRemoval(Card card) {
if (card.getSubtype(null).contains(SubType.AURA) || card.isInstant() || card.isSorcery()) {
if (card.isEnchantment() || card.isInstant() || card.isSorcery()) {
for (Ability ability : card.getAbilities()) {
for (Effect effect : ability.getEffects()) {
if (effect.getOutcome() == Outcome.Removal) {
log.debug("Found removal: " + card.getName());
if (isEffectRemoval(card, ability, effect) == 1){
return 1;
}
if (effect.getOutcome() == Outcome.Damage) {
if (effect instanceof DamageTargetEffect) {
DamageTargetEffect damageEffect = (DamageTargetEffect) effect;
if (damageEffect.getAmount() > 1) {
for (Target target : ability.getTargets()) {
if (target instanceof TargetCreaturePermanent || target instanceof TargetAnyTarget) {
log.debug("Found damage dealer: " + card.getName());
return 1;
}
}
}
}
}
if (effect.getOutcome() == Outcome.DestroyPermanent) {
for (Target target : ability.getTargets()) {
if (target instanceof TargetCreaturePermanent) {
log.debug("Found destroyer: " + card.getName());
return 1;
}
}
for (Mode mode: ability.getModes().values() ){
for (Effect effect: mode.getEffects()){
if (isEffectRemoval(card, ability, effect) == 1){
return 1;
}
}
}
}
}
return 0;
}
private static int isEffectRemoval(Card card, Ability ability, Effect effect){
if (effect.getOutcome() == Outcome.Removal) {
log.debug("Found removal: " + card.getName());
return 1;
}
//static List<Effect> removalEffects =[BoostTargetEffect,BoostEnchantedEffect]
if (effect instanceof BoostTargetEffect || effect instanceof BoostEnchantedEffect){
String text = effect.getText(null);
if (text.contains("/-")){
// toughness reducer, aka removal
return 1;
}
}
if (effect instanceof FightTargetsEffect || effect instanceof DamageWithPowerTargetEffect){
return 1;
}
if (effect.getOutcome() == Outcome.Damage || effect instanceof DamageTargetEffect) {
for (Target target : ability.getTargets()) {
if (!(target instanceof TargetPlayerOrPlaneswalker)){
log.debug("Found damage dealer: " + card.getName());
return 1;
}
}
}
if (effect.getOutcome() == Outcome.DestroyPermanent ||
effect instanceof DestroyTargetEffect ||
effect instanceof ExileTargetEffect ||
effect instanceof ExileUntilSourceLeavesEffect) {
for (Target target : ability.getTargets()) {
if (target instanceof TargetCreaturePermanent ||
target instanceof TargetAttackingCreature ||
target instanceof TargetAttackingOrBlockingCreature ||
target instanceof TargetPermanent) {
log.debug("Found destroyer/exiler: " + card.getName());
return 1;
}
}
}
return 0;
}
/**
* Return rating of the card.
*

View file

@ -38,7 +38,7 @@ public final class JusticeStrike extends CardImpl {
class JusticeStrikeEffect extends OneShotEffect {
public JusticeStrikeEffect() {
super(Outcome.Benefit);
super(Outcome.Removal);
this.staticText = "Target creature deals damage to itself equal to its power.";
}

View file

@ -19,7 +19,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu
}
public DontUntapInControllersUntapStepEnchantedEffect(String description) {
super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true);
super(Duration.WhileOnBattlefield, Outcome.Removal, false, true);
staticText = "Enchanted " + description + " doesn't untap during its controller's untap step";
}

View file

@ -14,7 +14,7 @@ import mage.players.Player;
public class ExileAndGainLifeEqualPowerTargetEffect extends OneShotEffect {
public ExileAndGainLifeEqualPowerTargetEffect() {
super(Outcome.GainLife);
super(Outcome.Removal);
staticText = "Exile target creature. Its controller gains life equal to its power";
}

View file

@ -19,7 +19,7 @@ import mage.util.CardUtil;
public class ExileUntilSourceLeavesEffect extends OneShotEffect {
public ExileUntilSourceLeavesEffect(String targetName) {
super(Outcome.Benefit);
super(Outcome.Removal);
this.staticText = "exile target " + targetName + " an opponent controls until {this} leaves the battlefield";
}

View file

@ -5,6 +5,7 @@ import mage.constants.AttachmentType;
import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.effects.RestrictionEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -14,7 +15,7 @@ import mage.game.permanent.Permanent;
public class CantAttackBlockAttachedEffect extends RestrictionEffect {
public CantAttackBlockAttachedEffect(AttachmentType attachmentType) {
super(Duration.WhileOnBattlefield);
super(Duration.WhileOnBattlefield, Outcome.Removal);
this.staticText = attachmentType.verb() + " creature can't attack or block";
}