magarena/src/magic/firemind/FiremindDuelRunner.java

201 lines
6.8 KiB
Java

package magic.firemind;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import magic.ai.MagicAIImpl;
import magic.data.CardDefinitions;
import magic.data.DuelConfig;
import magic.data.GeneralConfig;
import magic.data.settings.IntegerSetting;
import magic.headless.HeadlessGameController;
import magic.model.DuelPlayerConfig;
import magic.model.MagicDeckProfile;
import magic.model.MagicDuel;
import magic.model.MagicGame;
import magic.model.MagicGameLog;
import magic.model.MagicRandom;
import magic.model.player.AiProfile;
import magic.utility.DeckUtils;
import magic.utility.MagicSystem;
public class FiremindDuelRunner {
private static int games;
private static int str1 = 2;
private static int str2 = 2;
private static int life = 20;
private static int seed;
private static String deck1 = "";
private static String deck2 = "";
private static MagicAIImpl ai1 = MagicAIImpl.MCTS;
private static MagicAIImpl ai2 = MagicAIImpl.MCTS;
private static Duel currentDuel;
public static void main(String[] args) {
FiremindClient.setHostByEnvironment();
Duel duel = FiremindClient.popDeckJob();
if (duel == null) {
System.exit(1);
}
try {
final FiremindGameReport reporter = new FiremindGameReport(duel.id);
Thread.setDefaultUncaughtExceptionHandler(reporter);
System.out.println(duel.games_to_play + " Games to run");
File theDir = new File("duels/" + duel.id);
theDir.mkdir();
deck1 = saveDeckFile("firemind-duel-" + duel.id + "deck1",
duel.deck1_text);
deck2 = saveDeckFile("firemind-duel-" + duel.id + "deck2",
duel.deck2_text);
loadCardsInDeck(duel.deck1_text);
loadCardsInDeck(duel.deck2_text);
currentDuel = duel;
games = duel.games_to_play;
seed = duel.seed;
life = duel.life;
str1 = duel.strAi1;
str2 = duel.strAi2;
try {
ai1 = MagicAIImpl.valueOf(duel.ai1);
} catch (final IllegalArgumentException ex) {
System.err.println("Error: " + duel.ai1 + " is not valid AI");
}
try {
ai2 = MagicAIImpl.valueOf(duel.ai2);
} catch (final IllegalArgumentException ex) {
System.err.println("Error: " + duel.ai2 + " is not valid AI");
}
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
runDuel();
FiremindClient.postSuccess(duel.id);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
FiremindClient.postFailure(duel.id, sw.toString());
e.printStackTrace();
System.exit(2);
}
FiremindClient.resetChangedScripts();
System.exit(0);
}
private static MagicDuel setupDuel() {
// Set the random seed
if (seed != 0) {
MagicRandom.setRNGState(seed);
seed = MagicRandom.nextRNGInt() + 1;
}
// Set number of games.
final DuelConfig config = new DuelConfig();
config.setNrOfGames(games);
config.setStartLife(life);
// Set difficulty.
final MagicDuel testDuel = new MagicDuel(config);
final MagicDeckProfile profile = new MagicDeckProfile("bgruw");
final DuelPlayerConfig player1 = new DuelPlayerConfig(
AiProfile.create("Player1", ai1, str1),
profile
);
final DuelPlayerConfig player2 = new DuelPlayerConfig(
AiProfile.create("Player2", ai2, str2),
profile
);
testDuel.setPlayers(new DuelPlayerConfig[] { player1, player2 });
// Set the deck.
if (deck1.length() > 0) {
DeckUtils.loadAndSetPlayerDeck(deck1, testDuel.getPlayer(0));
}
if (deck2.length() > 0) {
DeckUtils.loadAndSetPlayerDeck(deck2, testDuel.getPlayer(1));
}
return testDuel;
}
public static void loadCardsInDeck(String decklist) {
Pattern r = Pattern.compile("^(\\d+) (.*)$");
for (String line : decklist.split("\\r\\n")) {
Matcher m = r.matcher(line);
if (m.find()) {
CardDefinitions.loadCardDefinition(m.group(2));
}
}
}
private static String saveDeckFile(String name, String content) {
try {
File deckFile = DeckUtils.getDecksFolder().resolve(name + ".dec").toFile();
deckFile.createNewFile();
Writer fw = Files.newBufferedWriter(deckFile.getAbsoluteFile().toPath(), UTF_8);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
return deckFile.getPath();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
private static void runDuel() {
int played = 0;
int wins = 0;
MagicGameLog.initialize();
final MagicDuel testDuel = setupDuel();
Date baseDate = new Date();
baseDate.setTime(0);
long started = System.currentTimeMillis();
while (testDuel.getGamesPlayed() < testDuel.getGamesTotal()) {
final MagicGame game = testDuel.nextGame();
game.setArtificial(true);
// maximum duration of a game is 60 minutes
final HeadlessGameController controller = new HeadlessGameController(
game, GeneralConfig.get(IntegerSetting.FIREMIND_MATCH_LIMIT) * 1000);
controller.runGame();
if (testDuel.getGamesPlayed() > played) {
played = testDuel.getGamesPlayed();
long diff = System.currentTimeMillis() - started;
String[] vers = MagicSystem.VERSION.split("\\.");
String log = MagicGameLog.getLogFileName();
FiremindClient.postGame(currentDuel.id, played, new Date(
baseDate.getTime() + diff),
testDuel.getGamesWon() > wins, Integer
.parseInt(vers[0]), Integer.parseInt(vers[1]),
log);
wins = testDuel.getGamesWon();
started = System.currentTimeMillis();
MagicGameLog.initialize();
}
}
System.out.println("Duel finished " + played + " of "
+ testDuel.getGamesTotal() + " run");
}
}