mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Improve logic for preventing loops
This commit is contained in:
@@ -75,10 +75,8 @@ public class ChooseCardAi extends SpellAbilityAi {
|
|||||||
return !choices.isEmpty();
|
return !choices.isEmpty();
|
||||||
} else if (aiLogic.equals("AtLeast2") || aiLogic.equals("BestBlocker")) {
|
} else if (aiLogic.equals("AtLeast2") || aiLogic.equals("BestBlocker")) {
|
||||||
return choices.size() >= 2;
|
return choices.size() >= 2;
|
||||||
} else if (aiLogic.equals("Clone") || aiLogic.equals("Vesuva")) {
|
} else if (aiLogic.equals("Clone")) {
|
||||||
final String filter = aiLogic.equals("Clone") ? "Permanent.YouDontCtrl,Permanent.nonLegendary"
|
final String filter = "Permanent.YouDontCtrl,Permanent.nonLegendary";
|
||||||
: "Permanent.YouDontCtrl+notnamedVesuva,Permanent.nonLegendary+notnamedVesuva";
|
|
||||||
|
|
||||||
choices = CardLists.getValidCards(choices, filter, host.getController(), host, sa);
|
choices = CardLists.getValidCards(choices, filter, host.getController(), host, sa);
|
||||||
return !choices.isEmpty();
|
return !choices.isEmpty();
|
||||||
} else if (aiLogic.equals("Never")) {
|
} else if (aiLogic.equals("Never")) {
|
||||||
@@ -173,18 +171,13 @@ public class ChooseCardAi extends SpellAbilityAi {
|
|||||||
options = CardLists.filter(options, Presets.UNTAPPED);
|
options = CardLists.filter(options, Presets.UNTAPPED);
|
||||||
}
|
}
|
||||||
choice = ComputerUtilCard.getBestCreatureAI(options);
|
choice = ComputerUtilCard.getBestCreatureAI(options);
|
||||||
} else if (logic.equals("Clone") || logic.equals("Vesuva")) {
|
} else if (logic.equals("Clone")) {
|
||||||
final String filter = logic.equals("Clone") ? "Permanent.YouDontCtrl,Permanent.nonLegendary" :
|
final String filter = "Permanent.YouDontCtrl,Permanent.nonLegendary";
|
||||||
"Permanent.YouDontCtrl+notnamedVesuva,Permanent.nonLegendary+notnamedVesuva";
|
|
||||||
|
|
||||||
CardCollection newOptions = CardLists.getValidCards(options, filter.split(","), ctrl, host, sa);
|
CardCollection newOptions = CardLists.getValidCards(options, filter.split(","), ctrl, host, sa);
|
||||||
if (!newOptions.isEmpty()) {
|
if (!newOptions.isEmpty()) {
|
||||||
options = newOptions;
|
options = newOptions;
|
||||||
}
|
}
|
||||||
choice = ComputerUtilCard.getBestAI(options);
|
choice = ComputerUtilCard.getBestAI(options);
|
||||||
if (logic.equals("Vesuva") && "Vesuva".equals(choice.getName())) {
|
|
||||||
choice = null;
|
|
||||||
}
|
|
||||||
} else if ("RandomNonLand".equals(logic)) {
|
} else if ("RandomNonLand".equals(logic)) {
|
||||||
options = CardLists.getValidCards(options, "Card.nonLand", host.getController(), host, sa);
|
options = CardLists.getValidCards(options, "Card.nonLand", host.getController(), host, sa);
|
||||||
choice = Aggregates.random(options);
|
choice = Aggregates.random(options);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package forge.ai.ability;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
|
||||||
import forge.ai.ComputerUtilCard;
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
@@ -11,6 +13,7 @@ import forge.game.card.Card;
|
|||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -179,18 +182,18 @@ public class CloneAi extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
protected Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional,
|
protected Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional,
|
||||||
Player targetedPlayer, Map<String, Object> params) {
|
Player targetedPlayer, Map<String, Object> params) {
|
||||||
|
|
||||||
final Card host = sa.getHostCard();
|
final Card host = sa.getHostCard();
|
||||||
|
final String name = host.getName();
|
||||||
final Player ctrl = host.getController();
|
final Player ctrl = host.getController();
|
||||||
|
|
||||||
final Card cloneTarget = getCloneTarget(sa);
|
final Card cloneTarget = getCloneTarget(sa);
|
||||||
final boolean isOpp = cloneTarget.getController().isOpponentOf(sa.getActivatingPlayer());
|
final boolean isOpp = cloneTarget.getController().isOpponentOf(sa.getActivatingPlayer());
|
||||||
|
|
||||||
final boolean isVesuva = "Vesuva".equals(host.getName());
|
final boolean isVesuva = "Vesuva".equals(name) || "Sculpting Steel".equals(name);
|
||||||
final boolean canCloneLegendary = "True".equalsIgnoreCase(sa.getParam("NonLegendary"));
|
final boolean canCloneLegendary = "True".equalsIgnoreCase(sa.getParam("NonLegendary"));
|
||||||
|
|
||||||
String filter = !isVesuva ? "Permanent.YouDontCtrl,Permanent.nonLegendary"
|
String filter = !isVesuva ? "Permanent.YouDontCtrl,Permanent.nonLegendary"
|
||||||
: "Permanent.YouDontCtrl+notnamedVesuva,Permanent.nonLegendary+notnamedVesuva";
|
: "Permanent.YouDontCtrl+notnamed" + name + ",Permanent.nonLegendary+notnamed" + name;
|
||||||
|
|
||||||
// TODO: rewrite this block so that this is done somehow more elegantly
|
// TODO: rewrite this block so that this is done somehow more elegantly
|
||||||
if (canCloneLegendary) {
|
if (canCloneLegendary) {
|
||||||
@@ -209,12 +212,13 @@ public class CloneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Card choice = isOpp ? ComputerUtilCard.getWorstAI(options) : ComputerUtilCard.getBestAI(options);
|
// prevent loop of choosing copy of same card
|
||||||
|
if (isVesuva) {
|
||||||
if (isVesuva && "Vesuva".equals(choice.getName())) {
|
options = CardLists.filter(options, Predicates.not(CardPredicates.sharesNameWith(host)));
|
||||||
choice = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Card choice = isOpp ? ComputerUtilCard.getWorstAI(options) : ComputerUtilCard.getBestAI(options);
|
||||||
|
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ ManaCost:3
|
|||||||
Types:Artifact
|
Types:Artifact
|
||||||
K:ETBReplacement:Copy:DBCopy:Optional
|
K:ETBReplacement:Copy:DBCopy:Optional
|
||||||
SVar:DBCopy:DB$ Clone | Choices$ Artifact.Other | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any artifact on the battlefield.
|
SVar:DBCopy:DB$ Clone | Choices$ Artifact.Other | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any artifact on the battlefield.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/sculpting_steel.jpg
|
SVar:NeedsToPlay:Artifact.YouDontCtrl+notnamedSculpting Steel,Artifact.YouCtrl+nonLegendary+notnamedSculpting Steel
|
||||||
Oracle:You may have Sculpting Steel enter the battlefield as a copy of any artifact on the battlefield.
|
Oracle:You may have Sculpting Steel enter the battlefield as a copy of any artifact on the battlefield.
|
||||||
|
|||||||
Reference in New Issue
Block a user