Ability to dump the current game state to a file in dev mode.

This commit is contained in:
Myrd
2014-12-16 19:04:05 +00:00
parent 8e3011294e
commit 85e7ad50b1
4 changed files with 126 additions and 0 deletions

View File

@@ -62,6 +62,16 @@ public enum CDev implements ICDoc {
MatchUtil.getHumanController().cheat().setupGameState(); MatchUtil.getHumanController().cheat().setupGameState();
} }
private final MouseListener madDump = new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
dumpGameState();
}
};
public void dumpGameState() {
MatchUtil.getHumanController().cheat().dumpGameState();
}
private final MouseListener madTutor = new MouseAdapter() { private final MouseListener madTutor = new MouseAdapter() {
@Override @Override
public void mousePressed(final MouseEvent e) { public void mousePressed(final MouseEvent e) {
@@ -181,6 +191,7 @@ public enum CDev implements ICDoc {
VDev.SINGLETON_INSTANCE.getLblViewAll().addMouseListener(madViewAll); VDev.SINGLETON_INSTANCE.getLblViewAll().addMouseListener(madViewAll);
VDev.SINGLETON_INSTANCE.getLblGenerateMana().addMouseListener(madMana); VDev.SINGLETON_INSTANCE.getLblGenerateMana().addMouseListener(madMana);
VDev.SINGLETON_INSTANCE.getLblSetupGame().addMouseListener(madSetup); VDev.SINGLETON_INSTANCE.getLblSetupGame().addMouseListener(madSetup);
VDev.SINGLETON_INSTANCE.getLblDumpGame().addMouseListener(madDump);
VDev.SINGLETON_INSTANCE.getLblTutor().addMouseListener(madTutor); VDev.SINGLETON_INSTANCE.getLblTutor().addMouseListener(madTutor);
VDev.SINGLETON_INSTANCE.getLblCardToHand().addMouseListener(madCardToHand); VDev.SINGLETON_INSTANCE.getLblCardToHand().addMouseListener(madCardToHand);
VDev.SINGLETON_INSTANCE.getLblCounterPermanent().addMouseListener(madCounter); VDev.SINGLETON_INSTANCE.getLblCounterPermanent().addMouseListener(madCounter);

View File

@@ -60,6 +60,7 @@ public enum VDev implements IVDoc<CDev> {
private final DevLabel lblViewAll = new DevLabel("View All Cards"); private final DevLabel lblViewAll = new DevLabel("View All Cards");
private final DevLabel lblGenerateMana = new DevLabel("Generate Mana"); private final DevLabel lblGenerateMana = new DevLabel("Generate Mana");
private final DevLabel lblSetupGame = new DevLabel("Setup Game State"); private final DevLabel lblSetupGame = new DevLabel("Setup Game State");
private final DevLabel lblDumpGame = new DevLabel("Dump Game State");
private final DevLabel lblTutor = new DevLabel("Tutor for Card"); private final DevLabel lblTutor = new DevLabel("Tutor for Card");
private final DevLabel lblCounterPermanent = new DevLabel("Add Counters to Permanent"); private final DevLabel lblCounterPermanent = new DevLabel("Add Counters to Permanent");
private final DevLabel lblTapPermanent = new DevLabel("Tap Permanents"); private final DevLabel lblTapPermanent = new DevLabel("Tap Permanents");
@@ -86,6 +87,7 @@ public enum VDev implements IVDoc<CDev> {
viewport.add(this.lblSetLife, halfConstraintsLeft); viewport.add(this.lblSetLife, halfConstraintsLeft);
viewport.add(this.lblWinGame, halfConstraints); viewport.add(this.lblWinGame, halfConstraints);
viewport.add(this.lblSetupGame, constraints); viewport.add(this.lblSetupGame, constraints);
viewport.add(this.lblDumpGame, constraints);
viewport.add(this.lblUnlimitedLands, constraints); viewport.add(this.lblUnlimitedLands, constraints);
viewport.add(this.lblCounterPermanent, constraints); viewport.add(this.lblCounterPermanent, constraints);
viewport.add(this.lblTapPermanent, halfConstraintsLeft); viewport.add(this.lblTapPermanent, halfConstraintsLeft);
@@ -157,6 +159,11 @@ public enum VDev implements IVDoc<CDev> {
return this.lblSetupGame; return this.lblSetupGame;
} }
/** @return {@link forge.screens.match.views.VDev.DevLabel} */
public DevLabel getLblDumpGame() {
return this.lblDumpGame;
}
/** @return {@link forge.screens.match.views.VDev.DevLabel} */ /** @return {@link forge.screens.match.views.VDev.DevLabel} */
public DevLabel getLblTutor() { public DevLabel getLblTutor() {
return this.lblTutor; return this.lblTutor;

View File

@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -18,8 +19,18 @@ import forge.game.player.Player;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.model.FModel; import forge.model.FModel;
import forge.util.FCollectionView;
public class GameState { public class GameState {
private static final Map<ZoneType, String> ZONES = new HashMap<ZoneType, String>();
static {
ZONES.put(ZoneType.Battlefield, "play");
ZONES.put(ZoneType.Hand, "hand");
ZONES.put(ZoneType.Graveyard, "graveyard");
ZONES.put(ZoneType.Library, "library");
ZONES.put(ZoneType.Exile, "exile");
}
private int humanLife = -1; private int humanLife = -1;
private int computerLife = -1; private int computerLife = -1;
private final Map<ZoneType, String> humanCardTexts = new EnumMap<ZoneType, String>(ZoneType.class); private final Map<ZoneType, String> humanCardTexts = new EnumMap<ZoneType, String>(ZoneType.class);
@@ -30,6 +41,85 @@ public class GameState {
public GameState() { public GameState() {
} }
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("humanlife=%d\n", humanLife));
sb.append(String.format("ailife=%d\n", computerLife));
sb.append(String.format("activeplayer=%s\n", tChangePlayer));
sb.append(String.format("activephase=%s\n", tChangePhase));
appendCards(humanCardTexts, "human", sb);
appendCards(aiCardTexts, "ai", sb);
return sb.toString();
}
private void appendCards(Map<ZoneType, String> cardTexts, String categoryPrefix, StringBuilder sb) {
for (Entry<ZoneType, String> kv : cardTexts.entrySet()) {
sb.append(String.format("%scardsin%s=%s\n", categoryPrefix, ZONES.get(kv.getKey()), kv.getValue()));
}
}
public void initFromGame(Game game) throws Exception {
FCollectionView<Player> players = game.getPlayers();
// Can only serialized a two player game with one AI and one human.
if (players.size() != 2) {
throw new Exception("Game not supported");
}
final Player human = game.getPlayers().get(0);
final Player ai = game.getPlayers().get(1);
if (!human.getController().isGuiPlayer() || !ai.getController().isAI()) {
throw new Exception("Game not supported");
}
humanLife = human.getLife();
computerLife = ai.getLife();
tChangePlayer = game.getPhaseHandler().getPlayerTurn() == ai ? "ai" : "human";
tChangePhase = game.getPhaseHandler().getPhase().toString();
aiCardTexts.clear();
humanCardTexts.clear();
for (ZoneType zone : ZONES.keySet()) {
for (Card card : game.getCardsIn(zone)) {
addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card);
}
}
}
private void addCard(ZoneType zoneType, Map<ZoneType, String> cardTexts, Card c) {
String value = cardTexts.get(zoneType);
String newText = c.getName();
if (zoneType == ZoneType.Battlefield) {
if (c.isTapped()) {
newText += "|Tapped:True";
}
if (c.isSick()) {
newText += "|SummonSick:True";
}
if (c.isFaceDown()) {
newText += "|FaceDown:True";
}
Map<CounterType, Integer> counters = c.getCounters();
if (!counters.isEmpty()) {
newText += "|Counters:";
boolean start = true;
for(Entry<CounterType, Integer> kv : counters.entrySet()) {
String str = kv.getKey().toString();
int count = kv.getValue();
for (int i = 0; i < count; i++) {
if (!start) {
newText += ",";
}
newText += str;
start = false;
}
}
}
}
if (value == null) {
value = newText;
} else {
value += ";" + newText;
}
cardTexts.put(zoneType, value);
}
public void parse(InputStream in) throws Exception { public void parse(InputStream in) throws Exception {
final BufferedReader br = new BufferedReader(new InputStreamReader(in)); final BufferedReader br = new BufferedReader(new InputStreamReader(in));

View File

@@ -1,8 +1,10 @@
package forge.player; package forge.player;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -1416,6 +1418,22 @@ public class PlayerControllerHuman extends PlayerController {
}); });
} }
public void dumpGameState() {
final GameState state = new GameState();
try {
state.initFromGame(game);
File f = GuiBase.getInterface().getSaveFile(new File(ForgeConstants.USER_GAMES_DIR, "state.txt"));
if (f != null) {
final BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write(state.toString());
bw.close();
}
} catch (Exception e) {
SOptionPane.showErrorDialog(e.getMessage());
e.printStackTrace();
}
}
public void setupGameState() { public void setupGameState() {
File gamesDir = new File(ForgeConstants.USER_GAMES_DIR); File gamesDir = new File(ForgeConstants.USER_GAMES_DIR);
if (!gamesDir.exists()) { // if the directory does not exist, try to create it if (!gamesDir.exists()) { // if the directory does not exist, try to create it