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, "Royal Assassin"); // 1/1
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit"); // 2/2
|
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit"); // 2/2
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn"); // 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");
|
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||||
|
|
||||||
// A cast Fiery Justice
|
// Cast Fiery Justice
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
|
||||||
addTarget(playerA, playerB); // 5 life to B
|
addTarget(playerA, playerB); // 5 life to B
|
||||||
addTarget(playerA, "Scute Mob^X=1"); // target 1
|
addTargetAmount(playerA, "Scute Mob" , 1); // target 1
|
||||||
addTarget(playerA, "Spellskite^X=4"); // target 2
|
addTargetAmount(playerA, "Spellskite", 4); // target 2
|
||||||
// B activate Spellskite, but can't change any targets cause it's already targeted
|
// 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");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||||
setChoice(playerB, "Yes"); // pay 2 life
|
setChoice(playerB, "Yes"); // pay 2 life
|
||||||
|
@ -288,7 +288,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
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");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||||
setChoice(playerB, "Yes"); // pay 2 life
|
setChoice(playerB, "Yes"); // pay 2 life
|
||||||
|
@ -319,9 +319,9 @@ public class SpellskiteTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.HAND, playerA, "Fiery Justice");
|
addCard(Zone.HAND, playerA, "Fiery Justice");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
|
||||||
addTarget(playerA, "Royal Assassin^X=1");
|
addTargetAmount(playerA, "Royal Assassin",1);
|
||||||
addTarget(playerA, "Blinking Spirit^X=2");
|
addTargetAmount(playerA, "Blinking Spirit",2);
|
||||||
addTarget(playerA, "Pearled Unicorn^X=2");
|
addTargetAmount(playerA, "Pearled Unicorn",2);
|
||||||
|
|
||||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
|
||||||
setChoice(playerB, "Yes"); // pay 2 life
|
setChoice(playerB, "Yes"); // pay 2 life
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.mage.test.player;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -16,6 +17,7 @@ import mage.abilities.costs.Costs;
|
||||||
import mage.abilities.costs.VariableCost;
|
import mage.abilities.costs.VariableCost;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||||
import mage.abilities.mana.ManaOptions;
|
import mage.abilities.mana.ManaOptions;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
@ -70,7 +72,7 @@ import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*;
|
||||||
@Ignore
|
@Ignore
|
||||||
public class TestPlayer implements Player {
|
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 TARGET_SKIP = "[target_skip]";
|
||||||
public static final String BLOCK_SKIP = "[block_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<PlayerAction> actions = new ArrayList<>();
|
||||||
private final List<String> choices = new ArrayList<>(); // choices stack for choice
|
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 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 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<>();
|
private final List<String> modesSet = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -153,6 +156,16 @@ public class TestPlayer implements Player {
|
||||||
targets.add(target);
|
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) {
|
public void addAlias(String name, UUID Id) {
|
||||||
aliases.put(name, Id);
|
aliases.put(name, Id);
|
||||||
}
|
}
|
||||||
|
@ -3277,59 +3290,40 @@ public class TestPlayer implements Player {
|
||||||
return computerPlayer.choose(outcome, cards, target, game);
|
return computerPlayer.choose(outcome, cards, target, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target,
|
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target,
|
||||||
Ability source, Game game
|
Ability source, Game game
|
||||||
) {
|
) {
|
||||||
// command format: targetName^X=3
|
if (!targetsAmount.isEmpty()) {
|
||||||
|
for (Iterator<Entry<String, Integer>> iterator = targetsAmount.entrySet().iterator(); iterator.hasNext();) {
|
||||||
// chooseTargetAmount calls by TargetAmount for EACH target cycle
|
Entry<String, Integer> targetRecord = iterator.next();
|
||||||
Assert.assertTrue("chooseTargetAmount supports only one target, but found " + target.getMaxNumberOfTargets(), target.getMaxNumberOfTargets() <= 1);
|
if (target.getAmountRemaining() > 0) {
|
||||||
Assert.assertNotEquals("chooseTargetAmount need remaining > 0", 0, target.getAmountRemaining());
|
target.possibleTargets(source.getSourceId(), source.getControllerId(), game).forEach((possibleTarget) -> {
|
||||||
|
MageObject objectPermanent = game.getObject(possibleTarget);
|
||||||
if (!targets.isEmpty()) {
|
Player objectPlayer = game.getPlayer(possibleTarget);
|
||||||
|
String objectName = objectPermanent != null ? objectPermanent.getName() : objectPlayer.getName();
|
||||||
boolean founded = false;
|
if (objectName.equals(targetRecord.getKey())) {
|
||||||
String foundedRecord = "";
|
if (!target.getTargets().contains(possibleTarget) && target.canTarget(possibleTarget, source, game)) {
|
||||||
CheckTargets:
|
// can select
|
||||||
for (String targetRecord : targets) {
|
target.addTarget(possibleTarget, targetRecord.getValue(), source, game);
|
||||||
String[] choiceSettings = targetRecord.split("\\^");
|
iterator.remove();
|
||||||
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 (founded) {
|
if (!target.isRequired() && target.getAmountRemaining() > 0) {
|
||||||
// all done
|
if (strictChooseMode) {
|
||||||
targets.remove(foundedRecord);
|
target.setAmountDefinition(StaticValue.get(0));
|
||||||
|
target.setAmount(source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
|
||||||
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
|
|
||||||
return computerPlayer.chooseTargetAmount(outcome, target, source, game);
|
return computerPlayer.chooseTargetAmount(outcome, target, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseMulligan(Game game
|
public boolean chooseMulligan(Game game
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public abstract class MageTestBase {
|
||||||
|
|
||||||
public static PluginClassLoader classLoader = new PluginClassLoader();
|
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\\})?");
|
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
|
* Expected results of the test. Read from test case in {@link String} based
|
||||||
* format:
|
* format:
|
||||||
* <p/>
|
* <p></p>
|
||||||
* Example: turn:1 result:won:ComputerA life:ComputerA:20 life:ComputerB:0
|
* Example: turn:1 result:won:ComputerA life:ComputerA:20 life:ComputerB:0
|
||||||
* battlefield:ComputerB:Tine Shrike:0 graveyard:ComputerB:Tine Shrike:1
|
* battlefield:ComputerB:Tine Shrike:0 graveyard:ComputerB:Tine Shrike:1
|
||||||
*/
|
*/
|
||||||
|
@ -103,24 +103,25 @@ public abstract class MageTestBase {
|
||||||
logger.info("Logging level: " + logger.getLevel());
|
logger.info("Logging level: " + logger.getLevel());
|
||||||
deleteSavedGames();
|
deleteSavedGames();
|
||||||
ConfigSettings config = ConfigSettings.instance;
|
ConfigSettings config = ConfigSettings.instance;
|
||||||
for (GamePlugin plugin : config.getGameTypes()) {
|
config.getGameTypes().forEach((gameType) -> {
|
||||||
GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
|
GameFactory.instance.addGameType(gameType.getName(), loadGameType(gameType), loadPlugin(gameType));
|
||||||
}
|
});
|
||||||
for (GamePlugin plugin : config.getTournamentTypes()) {
|
config.getTournamentTypes().forEach((tournamentType) -> {
|
||||||
TournamentFactory.instance.addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
|
TournamentFactory.instance.addTournamentType(tournamentType.getName(), loadTournamentType(tournamentType), loadPlugin(tournamentType));
|
||||||
}
|
});
|
||||||
for (Plugin plugin : config.getPlayerTypes()) {
|
config.getPlayerTypes().forEach((playerType) -> {
|
||||||
PlayerFactory.instance.addPlayerType(plugin.getName(), loadPlugin(plugin));
|
PlayerFactory.instance.addPlayerType(playerType.getName(), loadPlugin(playerType));
|
||||||
}
|
});
|
||||||
// for (Plugin plugin : config.getDeckTypes()) {
|
// for (Plugin plugin : config.getDeckTypes()) {
|
||||||
// DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
// DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
||||||
// }
|
// }
|
||||||
Copier.setLoader(classLoader);
|
Copier.setLoader(classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UseSpecificCatch")
|
||||||
private static Class<?> loadPlugin(Plugin plugin) {
|
private static Class<?> loadPlugin(Plugin plugin) {
|
||||||
try {
|
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());
|
logger.debug("Loading plugin: " + plugin.getClassName());
|
||||||
return Class.forName(plugin.getClassName(), true, classLoader);
|
return Class.forName(plugin.getClassName(), true, classLoader);
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
|
@ -133,11 +134,11 @@ public abstract class MageTestBase {
|
||||||
|
|
||||||
private static MatchType loadGameType(GamePlugin plugin) {
|
private static MatchType loadGameType(GamePlugin plugin) {
|
||||||
try {
|
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());
|
logger.debug("Loading game type: " + plugin.getClassName());
|
||||||
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
||||||
} catch (ClassNotFoundException ex) {
|
} 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) {
|
} catch (Exception ex) {
|
||||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||||
}
|
}
|
||||||
|
@ -146,7 +147,7 @@ public abstract class MageTestBase {
|
||||||
|
|
||||||
private static TournamentType loadTournamentType(GamePlugin plugin) {
|
private static TournamentType loadTournamentType(GamePlugin plugin) {
|
||||||
try {
|
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());
|
logger.info("Loading tournament type: " + plugin.getClassName());
|
||||||
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).getConstructor().newInstance();
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
|
|
|
@ -1604,6 +1604,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
||||||
player.addTarget("targetPlayer=" + targetPlayer.getName());
|
player.addTarget("targetPlayer=" + targetPlayer.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addTargetAmount(TestPlayer player, String target, int amount) {
|
||||||
|
player.addTargetAmount(target, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setDecknamePlayerA(String deckname) {
|
public void setDecknamePlayerA(String deckname) {
|
||||||
deckNameA = deckname;
|
deckNameA = deckname;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue