Add "card test" mode that tests all cards in a predefined scenario.
parent
39f14b40c8
commit
22a1471424
|
@ -0,0 +1,219 @@
|
||||||
|
package magic;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import magic.ai.MagicAI;
|
||||||
|
import magic.ai.MagicAIImpl;
|
||||||
|
import magic.data.CardDefinitions;
|
||||||
|
import magic.data.DuelConfig;
|
||||||
|
import magic.exception.handler.ConsoleExceptionHandler;
|
||||||
|
import magic.headless.HeadlessGameController;
|
||||||
|
import magic.model.DuelPlayerConfig;
|
||||||
|
import magic.model.MagicCardDefinition;
|
||||||
|
import magic.model.MagicDeckProfile;
|
||||||
|
import magic.model.MagicDuel;
|
||||||
|
import magic.model.MagicGame;
|
||||||
|
import magic.model.MagicPlayer;
|
||||||
|
import magic.model.phase.MagicMainPhase;
|
||||||
|
import magic.model.player.AiProfile;
|
||||||
|
import magic.test.TestGameBuilder;
|
||||||
|
import magic.utility.MagicSystem;
|
||||||
|
import magic.utility.ProgressReporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special kind of headless game, where every implemented
|
||||||
|
* card and token is used for a very short game in a predefined scenario.
|
||||||
|
*/
|
||||||
|
public class CardTest {
|
||||||
|
private static void parseCommandLine(CommandLineArgs cmdline) {
|
||||||
|
MagicAI.setMaxThreads(cmdline.getMaxThreads());
|
||||||
|
MagicSystem.setIsDevMode(cmdline.isDevMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final CommandLineArgs cmdline) {
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(new ConsoleExceptionHandler());
|
||||||
|
|
||||||
|
parseCommandLine(cmdline);
|
||||||
|
|
||||||
|
MagicSystem.initialize(new ProgressReporter());
|
||||||
|
|
||||||
|
System.out.println("=================== Card test ====================");
|
||||||
|
|
||||||
|
Collection<MagicCardDefinition> allC = CardDefinitions.getAllPlayableCardDefs();
|
||||||
|
|
||||||
|
List<String> cards = new ArrayList<>();
|
||||||
|
List<MagicCardDefinition> tokens = new ArrayList<>();
|
||||||
|
|
||||||
|
for (MagicCardDefinition def : allC) {
|
||||||
|
String name = def.getName();
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
// Manifest, morph, or alike ...
|
||||||
|
System.out.println("Def without name: " + def.getDistinctName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (def.isToken()) tokens.add(def);
|
||||||
|
else cards.add(name);
|
||||||
|
}
|
||||||
|
System.out.println("Cards: " + cards.size());
|
||||||
|
System.out.println("Tokens: " + tokens.size());
|
||||||
|
|
||||||
|
int t = 1;
|
||||||
|
for (MagicCardDefinition token : tokens) {
|
||||||
|
System.out.println("Testing token #" + t + ": " + token.getName());
|
||||||
|
t++;
|
||||||
|
MagicGame game = new TokenScenario(token).getGame();
|
||||||
|
game.setArtificial(true);
|
||||||
|
|
||||||
|
//5 seconds max for a quick match
|
||||||
|
final HeadlessGameController controller = new HeadlessGameController(
|
||||||
|
game, 5 * 1000
|
||||||
|
);
|
||||||
|
|
||||||
|
final long start_time = System.currentTimeMillis();
|
||||||
|
controller.runGame();
|
||||||
|
final double duration = (double) (System.currentTimeMillis() - start_time) / 1000;
|
||||||
|
|
||||||
|
System.out.printf("Token time: %.2fs : %s\n", duration, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
for (String name : cards) {
|
||||||
|
System.out.println("Testing card #" + n + ": " + name);
|
||||||
|
n++;
|
||||||
|
MagicGame game = new CardScenario(name).getGame();
|
||||||
|
game.setArtificial(true);
|
||||||
|
|
||||||
|
//5 seconds max for a quick match
|
||||||
|
final HeadlessGameController controller = new HeadlessGameController(
|
||||||
|
game, 5 * 1000
|
||||||
|
);
|
||||||
|
|
||||||
|
final long start_time = System.currentTimeMillis();
|
||||||
|
controller.runGame();
|
||||||
|
final double duration = (double) (System.currentTimeMillis() - start_time) / 1000;
|
||||||
|
|
||||||
|
System.out.printf("Time: %.2fs : %s\n", duration, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base scenario, where player starts with two tested cares in hand.
|
||||||
|
*/
|
||||||
|
private static class CardScenario extends BaseScenario {
|
||||||
|
private String testCard;
|
||||||
|
|
||||||
|
public CardScenario(String testCard) {
|
||||||
|
this.testCard = testCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareScenario(MagicPlayer player, MagicPlayer opponent) {
|
||||||
|
addToHand(player, testCard, 2);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base scenario, where player starts one tested token in play.
|
||||||
|
*/
|
||||||
|
private static class TokenScenario extends BaseScenario {
|
||||||
|
private MagicCardDefinition testToken;
|
||||||
|
|
||||||
|
public TokenScenario(MagicCardDefinition testToken) {
|
||||||
|
this.testToken = testToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareScenario(MagicPlayer player, MagicPlayer opponent) {
|
||||||
|
createPermanent(player, testToken, false, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base scenario - player has most likely enough mana to cast anything,
|
||||||
|
* opponent has at least one permanent of every type, so there would likely be some targets
|
||||||
|
* for variety of possible spells and effects.
|
||||||
|
*
|
||||||
|
* Libraries have only two cards (basic lands) in them, so the game is likely to end quickly.
|
||||||
|
*/
|
||||||
|
private static abstract class BaseScenario extends TestGameBuilder {
|
||||||
|
public abstract void prepareScenario(MagicPlayer player, MagicPlayer opponent);
|
||||||
|
|
||||||
|
public static MagicDuel createAiDuel(final MagicAIImpl aAiType, final int aAiLevel) {
|
||||||
|
// Set number of games.
|
||||||
|
final DuelConfig config = new DuelConfig();
|
||||||
|
config.setNrOfGames(1);
|
||||||
|
config.setStartLife(20);
|
||||||
|
|
||||||
|
AiProfile ai = AiProfile.create(aAiType, aAiLevel);
|
||||||
|
|
||||||
|
// Create players
|
||||||
|
config.setPlayerProfile(0, ai);
|
||||||
|
config.setPlayerProfile(1, ai);
|
||||||
|
|
||||||
|
final MagicDuel duel = new MagicDuel(config);
|
||||||
|
|
||||||
|
final MagicDeckProfile profile = new MagicDeckProfile("bgruw");
|
||||||
|
final DuelPlayerConfig player1 = new DuelPlayerConfig(ai, profile);
|
||||||
|
final DuelPlayerConfig player2 = new DuelPlayerConfig(ai, profile);
|
||||||
|
|
||||||
|
duel.setPlayers(new DuelPlayerConfig[]{player1, player2});
|
||||||
|
duel.setStartPlayer(0);
|
||||||
|
return duel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MagicDuel createAiDuel() {
|
||||||
|
return createAiDuel(MagicAIImpl.MMABFast, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MagicGame getGame() {
|
||||||
|
final MagicDuel duel = createAiDuel();
|
||||||
|
final MagicGame game = duel.nextGame();
|
||||||
|
game.setPhase(MagicMainPhase.getFirstInstance());
|
||||||
|
final MagicPlayer player = game.getPlayer(0);
|
||||||
|
final MagicPlayer opponent = game.getPlayer(1);
|
||||||
|
|
||||||
|
MagicPlayer P = player;
|
||||||
|
|
||||||
|
P.setLife(10);
|
||||||
|
addToLibrary(P, "Plains", 2);
|
||||||
|
// 5 mana of every color
|
||||||
|
createPermanent(P, "Plains", false, 5);
|
||||||
|
createPermanent(P, "Forest", false, 5);
|
||||||
|
createPermanent(P, "Island", false, 5);
|
||||||
|
createPermanent(P, "Swamp", false, 5);
|
||||||
|
createPermanent(P, "Mountain", false, 5);
|
||||||
|
// Own artifact creature
|
||||||
|
createPermanent(P, "Ornithopter", false, 1);
|
||||||
|
|
||||||
|
P = opponent;
|
||||||
|
|
||||||
|
P.setLife(10);
|
||||||
|
addToLibrary(P, "Plains", 2);
|
||||||
|
createPermanent(P, "Plains", false, 1);
|
||||||
|
createPermanent(P, "Forest", false, 1);
|
||||||
|
createPermanent(P, "Island", false, 1);
|
||||||
|
createPermanent(P, "Swamp", false, 1);
|
||||||
|
createPermanent(P, "Mountain", false, 1);
|
||||||
|
// Creature
|
||||||
|
createPermanent(P, "Wall of Ice", false, 1);
|
||||||
|
// Enchantment
|
||||||
|
createPermanent(P, "Orcish Oriflamme", false, 1);
|
||||||
|
// Artifact Creature
|
||||||
|
createPermanent(P, "Omega Myr", false, 1);
|
||||||
|
// Planeswalker
|
||||||
|
createPermanent(P, "Ajani Goldmane", false, 1);
|
||||||
|
// Sorcery
|
||||||
|
addToHand(P, "Angelic Edict", 1);
|
||||||
|
// Instant
|
||||||
|
addToHand(P, "Giant Growth", 1);
|
||||||
|
prepareScenario(player, opponent);
|
||||||
|
|
||||||
|
return game;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ class CommandLineArgs {
|
||||||
private String deck2 = "";
|
private String deck2 = "";
|
||||||
private boolean showFps = false;
|
private boolean showFps = false;
|
||||||
private boolean headless = false;
|
private boolean headless = false;
|
||||||
|
private boolean cardTest = false;
|
||||||
private int fps;
|
private int fps;
|
||||||
private int duels = 1;
|
private int duels = 1;
|
||||||
|
|
||||||
|
@ -74,6 +75,9 @@ class CommandLineArgs {
|
||||||
case "--headless":
|
case "--headless":
|
||||||
headless = true;
|
headless = true;
|
||||||
break;
|
break;
|
||||||
|
case "--cardtest":
|
||||||
|
cardTest = true;
|
||||||
|
break;
|
||||||
case "--duels": // the number of duels to play [--duels 1].
|
case "--duels": // the number of duels to play [--duels 1].
|
||||||
duels = Integer.parseInt(args[i + 1].trim());
|
duels = Integer.parseInt(args[i + 1].trim());
|
||||||
break;
|
break;
|
||||||
|
@ -209,6 +213,10 @@ class CommandLineArgs {
|
||||||
return headless;
|
return headless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isCardTest() {
|
||||||
|
return cardTest;
|
||||||
|
}
|
||||||
|
|
||||||
int getFPS() {
|
int getFPS() {
|
||||||
return fps;
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,12 @@ public class MagicMain {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transfer control to automatic card test
|
||||||
|
if (cmdline.isCardTest()) {
|
||||||
|
CardTest.main(cmdline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parseCommandLine(cmdline);
|
parseCommandLine(cmdline);
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new UiExceptionHandler());
|
Thread.setDefaultUncaughtExceptionHandler(new UiExceptionHandler());
|
||||||
|
|
|
@ -55,8 +55,13 @@ public abstract class TestGameBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicPermanent createPermanent(final MagicPlayer player, final String name, final boolean tapped, final int count) {
|
public static MagicPermanent createPermanent(final MagicPlayer player, final String name, final boolean tapped, final int count) {
|
||||||
|
final MagicCardDefinition cardDefinition = CardDefinitions.getCard(name);
|
||||||
|
return createPermanent(player, cardDefinition, tapped, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static MagicPermanent createPermanent(final MagicPlayer player, final MagicCardDefinition cardDefinition, final boolean tapped, final int count) {
|
||||||
final MagicGame game = player.getGame();
|
final MagicGame game = player.getGame();
|
||||||
final MagicCardDefinition cardDefinition=CardDefinitions.getCard(name);
|
|
||||||
MagicPermanent lastPermanent= MagicPermanent.NONE;
|
MagicPermanent lastPermanent= MagicPermanent.NONE;
|
||||||
for (int c=count;c>0;c--) {
|
for (int c=count;c>0;c--) {
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,5 @@ public class MagicManaCostTest {
|
||||||
|
|
||||||
MagicManaCost phy = MagicManaCost.create("{R/P}{G/P}{W/P}");
|
MagicManaCost phy = MagicManaCost.create("{R/P}{G/P}{W/P}");
|
||||||
assertEquals("{W/P}", phy.reducedBy(MagicManaCost.create("{R}{G}{U}")).toString());
|
assertEquals("{W/P}", phy.reducedBy(MagicManaCost.create("{R}{G}{U}")).toString());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue