diff --git a/forge-game/src/main/java/forge/game/GameOutcome.java b/forge-game/src/main/java/forge/game/GameOutcome.java index d6f3481c3d6..2cb077ef14a 100644 --- a/forge-game/src/main/java/forge/game/GameOutcome.java +++ b/forge-game/src/main/java/forge/game/GameOutcome.java @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -33,7 +33,7 @@ import java.util.Map.Entry; *

* GameInfo class. *

- * + * * @author Forge * @version $Id: GameOutcome.java 17608 2012-10-20 22:27:27Z Max mtg $ */ @@ -47,7 +47,7 @@ public final class GameOutcome implements Iterable lostCards; public final List wonCards; - + private AnteResult(List cards, boolean won) { // Need empty lists for other results for addition of change ownership cards if (won) { @@ -67,15 +67,20 @@ public final class GameOutcome implements Iterable cards) { return new AnteResult(cards, true); } - public static AnteResult lost(List cards) { return new AnteResult(cards, false); } + public static AnteResult won(List cards) { + return new AnteResult(cards, true); + } + + public static AnteResult lost(List cards) { + return new AnteResult(cards, false); + } } private int lastTurnNumber = 0; private int lifeDelta = 0; private int winningTeam = -1; - private final HashMap playerRating = new HashMap<>(); + private final HashMap playerRating = new HashMap<>(); private final HashMap playerNames = new HashMap<>(); public final Map anteResult = new HashMap<>(); @@ -83,21 +88,22 @@ public final class GameOutcome implements Iterable players) { winCondition = reason; - calculateLifeDelta(players); - - int winnersHealth = 0; - int opponentsHealth = 0; for (final Player p : players) { this.playerRating.put(p.getRegisteredPlayer(), p.getStats()); this.playerNames.put(p.getRegisteredPlayer(), p.getName()); - if (p.getOutcome().hasWon() && winCondition == GameEndReason.AllOpposingTeamsLost) { + if (winCondition == GameEndReason.AllOpposingTeamsLost && p.getOutcome().hasWon()) { // Only mark the WinningTeam when "Team mode" is on. winningTeam = p.getTeam(); } } + + // Unable to calculate lifeDelta between a winning and losing player whe a draw is in place + if (winCondition == GameEndReason.Draw) return; + int winnersHealth = 0; + int opponentsHealth = 0; for (final Player p : players) { if (p.getTeam() == winningTeam) { winnersHealth += p.getLife(); @@ -106,22 +112,22 @@ public final class GameOutcome implements Iterable players) { int opponentsHealth = 0; int winnersHealth = 0; - + for (Player p : players) { if (p.getOutcome().hasWon()) { winnersHealth += p.getLife(); - } - else { + } else { opponentsHealth += p.getLife(); } } - + lifeDelta = Math.max(0, winnersHealth - opponentsHealth); } @@ -150,7 +156,7 @@ public final class GameOutcome implements Iterable pair : playerRating.entrySet()) { + for (Entry pair : playerRating.entrySet()) { if (pair.getValue().getOutcome().hasWon()) { return pair.getKey(); } @@ -196,7 +202,7 @@ public final class GameOutcome implements Iterable getOutcomeStrings() { List outcomes = Lists.newArrayList(); - for(RegisteredPlayer player : playerNames.keySet()) { + for (RegisteredPlayer player : playerNames.keySet()) { outcomes.add(getOutcomeString(player)); } return outcomes; 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 49e3a1a6acc..35d2a2dbc35 100644 --- a/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java +++ b/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java @@ -1,34 +1,33 @@ package forge.view; +import forge.LobbyPlayer; +import forge.deck.Deck; +import forge.deck.DeckGroup; +import forge.deck.io.DeckSerializer; +import forge.game.*; +import forge.game.player.RegisteredPlayer; +import forge.model.FModel; +import forge.player.GamePlayerUtil; +import forge.properties.ForgeConstants; +import forge.tournament.system.*; +import forge.util.Lang; +import forge.util.TextUtil; +import forge.util.WordUtil; +import forge.util.storage.IStorage; +import org.apache.commons.lang3.time.StopWatch; + import java.io.File; import java.io.FilenameFilter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import forge.LobbyPlayer; -import forge.deck.DeckGroup; -import forge.game.*; -import forge.properties.ForgeConstants; -import forge.tournament.system.*; -import forge.util.TextUtil; -import forge.util.WordUtil; -import forge.util.storage.IStorage; -import org.apache.commons.lang3.time.StopWatch; - -import forge.deck.Deck; -import forge.deck.io.DeckSerializer; -import forge.game.player.RegisteredPlayer; -import forge.model.FModel; -import forge.player.GamePlayerUtil; -import forge.util.Lang; - public class SimulateMatch { public static void simulate(String[] args) { FModel.initialize(null, null); System.out.println("Simulation mode"); - if(args.length < 4) { + if (args.length < 4) { argumentHelp(); return; } @@ -49,11 +48,9 @@ public class SimulateMatch { options = new ArrayList<>(); params.put(a.substring(1), options); - } - else if (options != null) { + } else if (options != null) { options.add(a); - } - else { + } else { System.err.println("Illegal parameter usage"); return; } @@ -97,7 +94,7 @@ public class SimulateMatch { int i = 1; if (params.containsKey("d")) { - for(String deck : params.get("d")) { + for (String deck : params.get("d")) { Deck d = deckFromCommandLineParameter(deck, type); if (d == null) { System.out.println(TextUtil.concatNoSpace("Could not load deck - ", deck, ", match cannot start")); @@ -130,7 +127,7 @@ public class SimulateMatch { if (matchSize != 0) { int iGame = 0; - while(!mc.isMatchOver()) { + while (!mc.isMatchOver()) { // play games until the match ends simulateSingleMatch(mc, iGame, outputGamelog); iGame++; @@ -159,38 +156,26 @@ public class SimulateMatch { } - public static void simulateSingleMatch(final Match mc, int iGame, boolean outputGamelog) { final StopWatch sw = new StopWatch(); sw.start(); final Game g1 = mc.createGame(); // will run match in the same thread - - long startTime = System.currentTimeMillis(); try { - TimeLimitedCodeBlock.runWithTimeout(new Runnable() { - @Override - public void run() { - mc.startGame(g1); - sw.stop(); - } + TimeLimitedCodeBlock.runWithTimeout(() -> { + mc.startGame(g1); + sw.stop(); }, 120, TimeUnit.SECONDS); - } - catch (TimeoutException e) { + } catch (TimeoutException e) { System.out.println("Stopping slow match as draw"); - g1.setGameOver(GameEndReason.Draw); - sw.stop(); - }catch (Exception e){ + } catch (Exception | StackOverflowError e) { e.printStackTrace(); - g1.setGameOver(GameEndReason.Draw); - sw.stop(); - }catch(StackOverflowError e){ + } finally { g1.setGameOver(GameEndReason.Draw); sw.stop(); } - List log; if (outputGamelog) { log = g1.getGameLog().getLogEntries(null); @@ -198,15 +183,15 @@ public class SimulateMatch { log = g1.getGameLog().getLogEntries(GameLogEntryType.MATCH_RESULTS); } Collections.reverse(log); - for(GameLogEntry l : log) { + for (GameLogEntry l : log) { System.out.println(l); } // If both players life totals to 0 in a single turn, the game should end in a draw - if(g1.getOutcome().isDraw()){ - System.out.println(String.format("Game %d ended in a Draw! Took %d ms.", 1+iGame, sw.getTime())); + if (g1.getOutcome().isDraw()) { + System.out.printf("\nGame Result: Game %d ended in a Draw! Took %d ms.%n", 1 + iGame, sw.getTime()); } else { - System.out.println(String.format("\nGame %d ended in %d ms. %s has won!\n", 1+iGame, sw.getTime(), g1.getOutcome().getWinningLobbyPlayer().getName())); + System.out.printf("\nGame Result: Game %d ended in %d ms. %s has won!\n%n", 1 + iGame, sw.getTime(), g1.getOutcome().getWinningLobbyPlayer().getName()); } } @@ -219,7 +204,7 @@ public class SimulateMatch { List players = new ArrayList<>(); int numPlayers = 0; if (params.containsKey("d")) { - for(String deck : params.get("d")) { + for (String deck : params.get("d")) { Deck d = deckFromCommandLineParameter(deck, rules.getGameType()); if (d == null) { System.out.println(TextUtil.concatNoSpace("Could not load deck - ", deck, ", match cannot start")); @@ -239,7 +224,7 @@ public class SimulateMatch { if (!folder.isDirectory()) { System.out.println("Directory not found - " + foldName); } else { - for(File deck : folder.listFiles(new FilenameFilter() { + for (File deck : folder.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".dck"); @@ -281,16 +266,16 @@ public class SimulateMatch { System.out.println(TextUtil.concatNoSpace("Starting a ", tournament, " tournament with ", String.valueOf(numPlayers), " players over ", String.valueOf(tourney.getTotalRounds()), " rounds")); - while(!tourney.isTournamentOver()) { + while (!tourney.isTournamentOver()) { if (tourney.getActiveRound() != curRound) { if (curRound != 0) { System.out.println(TextUtil.concatNoSpace("End Round - ", String.valueOf(curRound))); } curRound = tourney.getActiveRound(); System.out.println(); - System.out.println(TextUtil.concatNoSpace("Round ", String.valueOf(curRound) ," Pairings:")); + System.out.println(TextUtil.concatNoSpace("Round ", String.valueOf(curRound), " Pairings:")); - for(TournamentPairing pairing : tourney.getActivePairings()) { + for (TournamentPairing pairing : tourney.getActivePairings()) { System.out.println(pairing.outputHeader()); } System.out.println(); @@ -311,10 +296,10 @@ public class SimulateMatch { int iGame = 0; while (!mc.isMatchOver()) { // play games until the match ends - try{ + try { simulateSingleMatch(mc, iGame, outputGamelog); iGame++; - } catch(Exception e) { + } catch (Exception e) { exceptions++; System.out.println(e.toString()); if (exceptions > 5) { @@ -349,10 +334,10 @@ public class SimulateMatch { private static Deck deckFromCommandLineParameter(String deckname, GameType type) { int dotpos = deckname.lastIndexOf('.'); - if(dotpos > 0 && dotpos == deckname.length()-4) { + if (dotpos > 0 && dotpos == deckname.length() - 4) { String baseDir = type.equals(GameType.Commander) ? ForgeConstants.DECK_COMMANDER_DIR : ForgeConstants.DECK_CONSTRUCTED_DIR; - return DeckSerializer.fromFile(new File(baseDir+deckname)); + return DeckSerializer.fromFile(new File(baseDir + deckname)); } IStorage deckStore = null;