Add "card test" mode that tests all cards in a predefined scenario.

master
Bilbo 2019-12-06 02:52:53 +01:00
parent 39f14b40c8
commit 22a1471424
5 changed files with 239 additions and 3 deletions

219
src/magic/CardTest.java Normal file
View File

@ -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;
}
}
}

View File

@ -22,6 +22,7 @@ class CommandLineArgs {
private String deck2 = "";
private boolean showFps = false;
private boolean headless = false;
private boolean cardTest = false;
private int fps;
private int duels = 1;
@ -74,6 +75,9 @@ class CommandLineArgs {
case "--headless":
headless = true;
break;
case "--cardtest":
cardTest = true;
break;
case "--duels": // the number of duels to play [--duels 1].
duels = Integer.parseInt(args[i + 1].trim());
break;
@ -209,6 +213,10 @@ class CommandLineArgs {
return headless;
}
boolean isCardTest() {
return cardTest;
}
int getFPS() {
return fps;
}

View File

@ -49,6 +49,12 @@ public class MagicMain {
return;
}
// transfer control to automatic card test
if (cmdline.isCardTest()) {
CardTest.main(cmdline);
return;
}
parseCommandLine(cmdline);
Thread.setDefaultUncaughtExceptionHandler(new UiExceptionHandler());

View File

@ -55,8 +55,13 @@ public abstract class TestGameBuilder {
}
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 MagicCardDefinition cardDefinition=CardDefinitions.getCard(name);
MagicPermanent lastPermanent= MagicPermanent.NONE;
for (int c=count;c>0;c--) {

View File

@ -52,7 +52,5 @@ public class MagicManaCostTest {
MagicManaCost phy = MagicManaCost.create("{R/P}{G/P}{W/P}");
assertEquals("{W/P}", phy.reducedBy(MagicManaCost.create("{R}{G}{U}")).toString());
}
}