mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
* Added better handling of TargetAmount for tests.
This commit is contained in:
parent
13b522989a
commit
ac2a59fdc2
4 changed files with 68 additions and 68 deletions
|
@ -246,14 +246,14 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Royal Assassin"); // 1/1
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit"); // 2/2
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn"); // 2/2
|
||||
|
||||
// Fiery Justice deals 5 damage divided as you choose among any number of target creatures and/or players. Target opponent gains 5 life.
|
||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
// A cast Fiery Justice
|
||||
// Cast Fiery Justice
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
|
||||
addTarget(playerA, playerB); // 5 life to B
|
||||
addTarget(playerA, "Scute Mob^X=1"); // target 1
|
||||
addTarget(playerA, "Spellskite^X=4"); // target 2
|
||||
addTargetAmount(playerA, "Scute Mob" , 1); // target 1
|
||||
addTargetAmount(playerA, "Spellskite", 4); // target 2
|
||||
// B activate Spellskite, but can't change any targets cause it's already targeted
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerB, "Yes"); // pay 2 life
|
||||
|
@ -288,7 +288,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Scute Mob^X=5");
|
||||
addTargetAmount(playerA, "Scute Mob", 5);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerB, "Yes"); // pay 2 life
|
||||
|
@ -319,9 +319,9 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||
addTarget(playerA, "Royal Assassin^X=1");
|
||||
addTarget(playerA, "Blinking Spirit^X=2");
|
||||
addTarget(playerA, "Pearled Unicorn^X=2");
|
||||
addTargetAmount(playerA, "Royal Assassin",1);
|
||||
addTargetAmount(playerA, "Blinking Spirit",2);
|
||||
addTargetAmount(playerA, "Pearled Unicorn",2);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||
setChoice(playerB, "Yes"); // pay 2 life
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.mage.test.player;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -16,6 +17,7 @@ import mage.abilities.costs.Costs;
|
|||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.abilities.mana.ManaOptions;
|
||||
import mage.cards.Card;
|
||||
|
@ -70,7 +72,7 @@ import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*;
|
|||
@Ignore
|
||||
public class TestPlayer implements Player {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TestPlayer.class);
|
||||
private static final Logger LOGGER = Logger.getLogger(TestPlayer.class);
|
||||
|
||||
public static final String TARGET_SKIP = "[target_skip]";
|
||||
public static final String BLOCK_SKIP = "[block_skip]";
|
||||
|
@ -82,6 +84,7 @@ public class TestPlayer implements Player {
|
|||
private final List<PlayerAction> actions = new ArrayList<>();
|
||||
private final List<String> choices = new ArrayList<>(); // choices stack for choice
|
||||
private final List<String> targets = new ArrayList<>(); // targets stack for choose (it's uses on empty direct target by cast command)
|
||||
private final LinkedHashMap<String, Integer> targetsAmount = new LinkedHashMap<>(); // targets and amounts for targets that also need to set an amount
|
||||
private final Map<String, UUID> aliases = new HashMap<>(); // aliases for game objects/players (use it for cards with same name to save and use)
|
||||
private final List<String> modesSet = new ArrayList<>();
|
||||
|
||||
|
@ -153,6 +156,16 @@ public class TestPlayer implements Player {
|
|||
targets.add(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for TargetAmount classes that include also an amount beside the target like TargetPermanentAmount
|
||||
*
|
||||
* @param targetName
|
||||
* @param amount
|
||||
*/
|
||||
public void addTargetAmount(String targetName, Integer amount) {
|
||||
targetsAmount.put(targetName, amount);
|
||||
}
|
||||
|
||||
public void addAlias(String name, UUID Id) {
|
||||
aliases.put(name, Id);
|
||||
}
|
||||
|
@ -3277,59 +3290,40 @@ public class TestPlayer implements Player {
|
|||
return computerPlayer.choose(outcome, cards, target, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
// command format: targetName^X=3
|
||||
|
||||
// chooseTargetAmount calls by TargetAmount for EACH target cycle
|
||||
Assert.assertTrue("chooseTargetAmount supports only one target, but found " + target.getMaxNumberOfTargets(), target.getMaxNumberOfTargets() <= 1);
|
||||
Assert.assertNotEquals("chooseTargetAmount need remaining > 0", 0, target.getAmountRemaining());
|
||||
|
||||
if (!targets.isEmpty()) {
|
||||
|
||||
boolean founded = false;
|
||||
String foundedRecord = "";
|
||||
CheckTargets:
|
||||
for (String targetRecord : targets) {
|
||||
String[] choiceSettings = targetRecord.split("\\^");
|
||||
if (choiceSettings.length == 2 && choiceSettings[1].startsWith("X=")) {
|
||||
// can choice
|
||||
String choiceName = choiceSettings[0];
|
||||
int choiceAmount = Integer.parseInt(choiceSettings[1].substring(2));
|
||||
|
||||
Assert.assertNotEquals("choice amount must be not zero", 0, choiceAmount);
|
||||
Assert.assertTrue("choice amount " + choiceAmount + "must be <= remaining " + target.getAmountRemaining(), choiceAmount <= target.getAmountRemaining());
|
||||
|
||||
for (UUID possibleTarget : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
||||
MageObject objectPermanent = game.getObject(possibleTarget);
|
||||
Player objectPlayer = game.getPlayer(possibleTarget);
|
||||
String objectName = objectPermanent != null ? objectPermanent.getName() : objectPlayer.getName();
|
||||
if (objectName.equals(choiceName)) {
|
||||
if (!target.getTargets().contains(possibleTarget) && target.canTarget(possibleTarget, source, game)) {
|
||||
// can select
|
||||
target.addTarget(possibleTarget, choiceAmount, source, game);
|
||||
founded = true;
|
||||
foundedRecord = targetRecord;
|
||||
break CheckTargets;
|
||||
if (!targetsAmount.isEmpty()) {
|
||||
for (Iterator<Entry<String, Integer>> iterator = targetsAmount.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<String, Integer> targetRecord = iterator.next();
|
||||
if (target.getAmountRemaining() > 0) {
|
||||
target.possibleTargets(source.getSourceId(), source.getControllerId(), game).forEach((possibleTarget) -> {
|
||||
MageObject objectPermanent = game.getObject(possibleTarget);
|
||||
Player objectPlayer = game.getPlayer(possibleTarget);
|
||||
String objectName = objectPermanent != null ? objectPermanent.getName() : objectPlayer.getName();
|
||||
if (objectName.equals(targetRecord.getKey())) {
|
||||
if (!target.getTargets().contains(possibleTarget) && target.canTarget(possibleTarget, source, game)) {
|
||||
// can select
|
||||
target.addTarget(possibleTarget, targetRecord.getValue(), source, game);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (founded) {
|
||||
// all done
|
||||
targets.remove(foundedRecord);
|
||||
}
|
||||
}
|
||||
if (!target.isRequired() && target.getAmountRemaining() > 0) {
|
||||
if (strictChooseMode) {
|
||||
target.setAmountDefinition(StaticValue.get(0));
|
||||
target.setAmount(source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
|
||||
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
|
||||
return computerPlayer.chooseTargetAmount(outcome, target, source, game);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean chooseMulligan(Game game
|
||||
) {
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class MageTestBase {
|
|||
|
||||
public static PluginClassLoader classLoader = new PluginClassLoader();
|
||||
|
||||
private static final String pluginFolder = "plugins";
|
||||
private static final String PLUGIN_FOLDER = "plugins";
|
||||
|
||||
protected Pattern pattern = Pattern.compile("([a-zA-Z]*):([\\w]*):([a-zA-Z ,\\-.!'\\d]*):([\\d]*)(:\\{tapped\\})?");
|
||||
|
||||
|
@ -88,7 +88,7 @@ public abstract class MageTestBase {
|
|||
/**
|
||||
* Expected results of the test. Read from test case in {@link String} based
|
||||
* format:
|
||||
* <p/>
|
||||
* <p></p>
|
||||
* Example: turn:1 result:won:ComputerA life:ComputerA:20 life:ComputerB:0
|
||||
* battlefield:ComputerB:Tine Shrike:0 graveyard:ComputerB:Tine Shrike:1
|
||||
*/
|
||||
|
@ -103,24 +103,25 @@ public abstract class MageTestBase {
|
|||
logger.info("Logging level: " + logger.getLevel());
|
||||
deleteSavedGames();
|
||||
ConfigSettings config = ConfigSettings.instance;
|
||||
for (GamePlugin plugin : config.getGameTypes()) {
|
||||
GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
|
||||
}
|
||||
for (GamePlugin plugin : config.getTournamentTypes()) {
|
||||
TournamentFactory.instance.addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
|
||||
}
|
||||
for (Plugin plugin : config.getPlayerTypes()) {
|
||||
PlayerFactory.instance.addPlayerType(plugin.getName(), loadPlugin(plugin));
|
||||
}
|
||||
config.getGameTypes().forEach((gameType) -> {
|
||||
GameFactory.instance.addGameType(gameType.getName(), loadGameType(gameType), loadPlugin(gameType));
|
||||
});
|
||||
config.getTournamentTypes().forEach((tournamentType) -> {
|
||||
TournamentFactory.instance.addTournamentType(tournamentType.getName(), loadTournamentType(tournamentType), loadPlugin(tournamentType));
|
||||
});
|
||||
config.getPlayerTypes().forEach((playerType) -> {
|
||||
PlayerFactory.instance.addPlayerType(playerType.getName(), loadPlugin(playerType));
|
||||
});
|
||||
// for (Plugin plugin : config.getDeckTypes()) {
|
||||
// DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
||||
// }
|
||||
Copier.setLoader(classLoader);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UseSpecificCatch")
|
||||
private static Class<?> loadPlugin(Plugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + '/' + plugin.getJar()).toURI().toURL());
|
||||
classLoader.addURL(new File(PLUGIN_FOLDER + '/' + plugin.getJar()).toURI().toURL());
|
||||
logger.debug("Loading plugin: " + plugin.getClassName());
|
||||
return Class.forName(plugin.getClassName(), true, classLoader);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
|
@ -133,11 +134,11 @@ public abstract class MageTestBase {
|
|||
|
||||
private static MatchType loadGameType(GamePlugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + '/' + plugin.getJar()).toURI().toURL());
|
||||
classLoader.addURL(new File(PLUGIN_FOLDER + '/' + plugin.getJar()).toURI().toURL());
|
||||
logger.debug("Loading game type: " + plugin.getClassName());
|
||||
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder");
|
||||
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder", ex);
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||
}
|
||||
|
@ -146,7 +147,7 @@ public abstract class MageTestBase {
|
|||
|
||||
private static TournamentType loadTournamentType(GamePlugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + '/' + plugin.getJar()).toURI().toURL());
|
||||
classLoader.addURL(new File(PLUGIN_FOLDER + '/' + plugin.getJar()).toURI().toURL());
|
||||
logger.info("Loading tournament type: " + plugin.getClassName());
|
||||
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
|
|
|
@ -1604,6 +1604,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
player.addTarget("targetPlayer=" + targetPlayer.getName());
|
||||
}
|
||||
|
||||
public void addTargetAmount(TestPlayer player, String target, int amount) {
|
||||
player.addTargetAmount(target, amount);
|
||||
}
|
||||
|
||||
|
||||
public void setDecknamePlayerA(String deckname) {
|
||||
deckNameA = deckname;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue