diff --git a/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java b/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java index b0611e1ab59..02f63b10dbb 100644 --- a/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java +++ b/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java @@ -1,10 +1,10 @@ package forge.view; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; +import forge.util.storage.IStorage; +import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.time.StopWatch; import forge.deck.Deck; @@ -24,39 +24,95 @@ public class SimulateMatch { FModel.initialize(null); System.out.println("Simulation mode"); - if(args.length < 3 ) { - System.out.println("Syntax: forge.exe sim [N]"); - System.out.println("\tsim - stands for simulation mode"); - System.out.println("\tdeck1 (or deck2) - constructed deck name or filename (has to be quoted when contains multiple words)"); - System.out.println("\tdeck is treated as file if it ends with a dot followed by three numbers or letters"); - System.out.println("\tN - number of games, defaults to 1"); + if(args.length < 4) { + argumentHelp(); return; } - Deck d1 = deckFromCommandLineParameter(args[1]); - Deck d2 = deckFromCommandLineParameter(args[2]); - if(d1 == null || d2 == null) { - System.out.println("One of decks could not be loaded, match cannot start"); - return; + + final Map> params = new HashMap<>(); + List options = null; + + for (int i = 1; i < args.length; i++) { + // "sim" is in the 0th slot + final String a = args[i]; + + if (a.charAt(0) == '-') { + if (a.length() < 2) { + System.err.println("Error at argument " + a); + argumentHelp(); + return; + } + + options = new ArrayList<>(); + params.put(a.substring(1), options); + } + else if (options != null) { + options.add(a); + } + else { + System.err.println("Illegal parameter usage"); + return; + } } - - int nGames = args.length >= 4 ? Integer.parseInt(args[3]) : 1; - - System.out.println(String.format("Ai-%s vs Ai_%s - %s", d1.getName(), d2.getName(), Lang.nounWithNumeral(nGames, "game"))); - + + //final Map> params = new HashMap<>(); + + int nGames = 1; + if (params.containsKey("n")) { + // Number of games should only be a single string + nGames = Integer.parseInt(params.get("n").get(0)); + } + + GameType type = GameType.Constructed; + if (params.containsKey("f")) { + type = GameType.valueOf(WordUtils.capitalize(params.get("f").get(0))); + } + List pp = new ArrayList(); - pp.add(new RegisteredPlayer(d1).setPlayer(GamePlayerUtil.createAiPlayer("Ai-" + d1.getName(), 0))); - pp.add(new RegisteredPlayer(d2).setPlayer(GamePlayerUtil.createAiPlayer("Ai_" + d2.getName(), 1))); - GameRules rules = new GameRules(GameType.Constructed); + + StringBuilder sb = new StringBuilder(); + + int i = 1; + for(String deck : params.get("d")) { + Deck d = deckFromCommandLineParameter(deck, type); + if (d == null) { + System.out.println("One of decks could not be loaded, match cannot start"); + return; + } + if (i > 1) { + sb.append(" vs "); + } + String name = String.format("Ai(%s)-%s", i, d.getName()); + sb.append(name); + + pp.add(new RegisteredPlayer(d).setPlayer(GamePlayerUtil.createAiPlayer(name, i-1))); + i++; + } + sb.append(" - ").append(Lang.nounWithNumeral(nGames, "game")).append(" of ").append(type); + + System.out.println(sb.toString()); + + GameRules rules = new GameRules(type); Match mc = new Match(rules, pp, "Test"); for (int iGame = 0; iGame < nGames; iGame++) { simulateSingleMatch(mc, iGame); } System.out.flush(); } + + private static void argumentHelp() { + System.out.println("Syntax: forge.exe sim -d ... -n [N] -f [F]"); + System.out.println("\tsim - stands for simulation mode"); + System.out.println("\tdeck1 (or deck2,...,X) - constructed deck name or filename (has to be quoted when contains multiple words)"); + System.out.println("\tdeck is treated as file if it ends with a dot followed by three numbers or letters"); + System.out.println("\tN - number of games, defaults to 1"); + System.out.println("\tF - format of games, defaults to constructed"); + } + /** * TODO: Write javadoc for this method. - * @param sw - * @param pp + * @param mc + * @param iGame */ private static void simulateSingleMatch(Match mc, int iGame) { StopWatch sw = new StopWatch(); @@ -66,22 +122,31 @@ public class SimulateMatch { // will run match in the same thread mc.startGame(g1); sw.stop(); - + List log = g1.getGameLog().getLogEntries(null); Collections.reverse(log); - + for(GameLogEntry l : log) System.out.println(l); System.out.println(String.format("\nGame %d ended in %d ms. %s has won!\n", 1+iGame, sw.getTime(), g1.getOutcome().getWinningLobbyPlayer().getName())); } - - private static Deck deckFromCommandLineParameter(String deckname) { + private static Deck deckFromCommandLineParameter(String deckname, GameType type) { int dotpos = deckname.lastIndexOf('.'); if(dotpos > 0 && dotpos == deckname.length()-4) return DeckSerializer.fromFile(new File(deckname)); - return FModel.getDecks().getConstructed().get(deckname); + + IStorage deckStore = null; + + // Add other game types here... + if (type.equals(GameType.Commander)) { + deckStore = FModel.getDecks().getCommander(); + } else { + deckStore = FModel.getDecks().getConstructed(); + } + + return deckStore.get(deckname); } -} +} \ No newline at end of file