diff --git a/.gitattributes b/.gitattributes index c66b6296468..cf72bc367e2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9761,7 +9761,6 @@ src/main/java/forge/game/GameLossReason.java -text src/main/java/forge/game/GamePlayerRating.java -text src/main/java/forge/game/GameSummary.java svneol=native#text/plain src/main/java/forge/game/GameType.java -text -src/main/java/forge/game/PlayerIndex.java -text src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain src/main/java/forge/game/limited/BoosterDraft_1.java svneol=native#text/plain diff --git a/src/main/java/forge/AllZone.java b/src/main/java/forge/AllZone.java index 15756459743..08bd0c528ab 100644 --- a/src/main/java/forge/AllZone.java +++ b/src/main/java/forge/AllZone.java @@ -55,9 +55,6 @@ public final class AllZone implements NewConstants { /** Constant inputControl. */ private static final InputControl INPUT_CONTROL = new InputControl(Singletons.getModel()); - /** Game state observer gameInfo collects statistics and players' performance. */ - private static GameSummary gameInfo = new GameSummary(); - /** * Match State for challenges are stored in a QuestMatchState class instance. */ @@ -301,7 +298,7 @@ public final class AllZone implements NewConstants { * @since 1.0.15 */ public static GameSummary getGameInfo() { - return gameInfo; + return Singletons.getModel().getGameState().getGameInfo(); } /** @@ -439,26 +436,15 @@ public final class AllZone implements NewConstants { */ public static void newGameCleanup() { - gameInfo = new GameSummary(); - - getHumanPlayer().reset(); - getComputerPlayer().reset(); - - getPhase().reset(); - getStack().reset(); - getCombat().reset(); + Singletons.getModel().getGameState().newGameCleanup(); + + getDisplay().showCombat(""); getDisplay().loadPrefs(); - for (Player p : Singletons.getModel().getGameState().getPlayers()) { - for(Zone z : Player.ALL_ZONES) { - p.getZone(z).reset(); - } - } getInputControl().clearInput(); - getStaticEffects().reset(); getColorChanger().reset(); // player.reset() now handles this diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 4ff8efffd6d..96685eed513 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -22,7 +22,6 @@ import forge.deck.Deck; import forge.game.GameEndReason; import forge.game.GameSummary; import forge.game.GameType; -import forge.game.PlayerIndex; import forge.gui.GuiUtils; import forge.gui.input.Input_Mulligan; import forge.gui.input.Input_PayManaCost; @@ -598,9 +597,9 @@ public class GameAction { humanWins = true; if (human.getAltWin()) { - game.end(GameEndReason.WinsGameSpellEffect, PlayerIndex.HUMAN, human.getWinConditionSource()); + game.end(GameEndReason.WinsGameSpellEffect, human.getName(), human.getWinConditionSource()); } else { - game.end(GameEndReason.AllOpponentsLost, PlayerIndex.HUMAN, null); + game.end(GameEndReason.AllOpponentsLost, human.getName(), null); } } @@ -608,14 +607,14 @@ public class GameAction { if (computer.hasWon() || human.hasLost()) { if (humanWins) { // both players won/lost at the same time. - game.end(GameEndReason.Draw, PlayerIndex.DRAW, null); + game.end(GameEndReason.Draw, null, null); } else { computerWins = true; if (computer.getAltWin()) { - game.end(GameEndReason.WinsGameSpellEffect, PlayerIndex.AI, computer.getWinConditionSource()); + game.end(GameEndReason.WinsGameSpellEffect, computer.getName(), computer.getWinConditionSource()); } else { - game.end(GameEndReason.AllOpponentsLost, PlayerIndex.AI, null); + game.end(GameEndReason.AllOpponentsLost, computer.getName(), null); } } @@ -623,8 +622,8 @@ public class GameAction { boolean isGameDone = humanWins || computerWins; if (isGameDone) { - game.getPlayerRating(PlayerIndex.AI).setLossReason(computer.getLossState(), computer.getLossConditionSource()); - game.getPlayerRating(PlayerIndex.HUMAN).setLossReason(human.getLossState(), human.getLossConditionSource()); + game.getPlayerRating(computer.getName()).setLossReason(computer.getLossState(), computer.getLossConditionSource()); + game.getPlayerRating(human.getName()).setLossReason(human.getLossState(), human.getLossConditionSource()); AllZone.getMatchState().addGamePlayed(game); } @@ -1245,7 +1244,7 @@ public class GameAction { } else { seeWhoPlaysFirst_CoinToss(); } - } else if (AllZone.getMatchState().hasHumanWonLastGame()) { + } else if (AllZone.getMatchState().hasWonLastGame(AllZone.getHumanPlayer().getName())) { // if player won last, AI starts computerStartsGame(); } @@ -1517,8 +1516,9 @@ public class GameAction { *

computerStartsGame.

*/ public final void computerStartsGame() { - AllZone.getPhase().setPlayerTurn(AllZone.getComputerPlayer()); - AllZone.getGameInfo().setPlayerWhoGotFirstTurn(PlayerIndex.AI); + Player computer = AllZone.getComputerPlayer(); + AllZone.getPhase().setPlayerTurn(computer); + AllZone.getGameInfo().setPlayerWhoGotFirstTurn(computer.getName()); } //if Card had the type "Aura" this method would always return true, since local enchantments are always attached to something diff --git a/src/main/java/forge/Gui_WinLose.java b/src/main/java/forge/Gui_WinLose.java index 4fddbe16446..a0bc477fdfd 100644 --- a/src/main/java/forge/Gui_WinLose.java +++ b/src/main/java/forge/Gui_WinLose.java @@ -6,7 +6,6 @@ import forge.game.GameFormat; import forge.game.GameLossReason; import forge.game.GamePlayerRating; import forge.game.GameSummary; -import forge.game.PlayerIndex; import forge.gui.CardListViewer; import forge.gui.ListChooser; import forge.item.CardPrinted; @@ -113,13 +112,14 @@ public class Gui_WinLose extends JFrame implements NewConstants { restartButton.setEnabled(!isQuestMode); // For quest always disabled, otherwise always on //show Wins and Loses - int humanWins = model.match.getGamesCountWonByHuman(); - int humanLosses = model.match.getGamesCountLostByHuman(); + Player human = AllZone.getHumanPlayer(); + int humanWins = model.match.countGamesWonBy(human.getName()); + int humanLosses = model.match.getGamesPlayedCount() - humanWins; statsLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.WON) + humanWins + ForgeProps.getLocalized(WINLOSE_TEXT.LOST) + humanLosses); //show "You Won" or "You Lost" - if (model.match.hasHumanWonLastGame()) { + if (model.match.hasWonLastGame(human.getName())) { titleLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.WIN)); } else { titleLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.LOSE)); @@ -244,15 +244,16 @@ public class Gui_WinLose extends JFrame implements NewConstants { StringBuilder sb = new StringBuilder(""); boolean hasNeverLost = true; + Player computer = AllZone.getComputerPlayer(); for (GameSummary game : matchState.getGamesPlayed()) { - if (game.isAIWinner()) { - hasNeverLost = true; + if (game.isWinner(computer.getName())) { + hasNeverLost = false; continue; // no rewards for losing a game } - GamePlayerRating aiRating = game.getPlayerRating(PlayerIndex.AI); - GamePlayerRating humanRating = game.getPlayerRating(PlayerIndex.HUMAN); + GamePlayerRating aiRating = game.getPlayerRating(computer.getName()); + GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName()); GameLossReason whyAiLost = aiRating.getLossReason(); int rewardAltWinCondition = q.getRewards().getCreditsRewardForAltWin(whyAiLost); @@ -344,7 +345,7 @@ public class Gui_WinLose extends JFrame implements NewConstants { } else { //Quest boolean wonMatch = false; - if (model.match.isMatchWonByHuman()) { + if (model.match.isMatchWonBy(AllZone.getHumanPlayer().getName())) { model.quest.addWin(); wonMatch = true; } else { diff --git a/src/main/java/forge/game/GameSummary.java b/src/main/java/forge/game/GameSummary.java index c1076630078..9a3ac3e1d32 100644 --- a/src/main/java/forge/game/GameSummary.java +++ b/src/main/java/forge/game/GameSummary.java @@ -1,5 +1,8 @@ package forge.game; +import java.util.HashMap; +import java.util.Map; + /** *

GameInfo class.

@@ -8,49 +11,44 @@ package forge.game; * @version $Id$ */ -// This should be divided into two: the very summary (immutable with only getters) and +// This class might be divided in two parts: the very summary (immutable with only getters) and // GameObserver class - who should be notified of any considerable ingame event -public class GameSummary { - protected int playerWinner = PlayerIndex.UNDEFINED; - protected int playerGotFirstTurn = PlayerIndex.UNDEFINED; +public final class GameSummary { + protected String playerWinner = "Nobody"; + protected String playerGotFirstTurn = "Nobody"; protected int lastTurnNumber = 0; protected GameEndReason winCondition; protected String spellEffectWin; - protected GamePlayerRating playerRating[] = new GamePlayerRating[2/*players*/]; + protected final Map playerRating = new HashMap(); - public GameSummary() + public GameSummary(String... names) { - playerRating[PlayerIndex.AI] = new GamePlayerRating(); - playerRating[PlayerIndex.HUMAN] = new GamePlayerRating(); + for (String n : names) { + playerRating.put(n, new GamePlayerRating()); + } } - public final void end( final GameEndReason condition, int iPlayerWinner, String spellEffectWin ) + public final void end( final GameEndReason condition, String winner, String spellEffect ) { winCondition = condition; - playerWinner = iPlayerWinner; - this.spellEffectWin = spellEffectWin; + playerWinner = winner; + spellEffectWin = spellEffect; } - - public final boolean isHumanWinner() { return PlayerIndex.HUMAN == playerWinner; } - public final boolean isAIWinner() { return PlayerIndex.AI == playerWinner; } - public final boolean isDraw() { return PlayerIndex.DRAW == playerWinner; } + public final boolean isDraw() { return null == playerWinner; } + public final boolean isWinner(String name) { return name != null && name.equals(playerWinner); } + public String getWinner() { return playerWinner; } public GameEndReason getWinCondition() { return winCondition; } - public GamePlayerRating getPlayerRating(int iPlayer) { - if (iPlayer >= 0 && iPlayer < playerRating.length) { - return playerRating[iPlayer]; - } - return null; - } + public GamePlayerRating getPlayerRating(String name) { return playerRating.get(name); } public int getTurnGameEnded() { return lastTurnNumber; } - public final void setPlayerWhoGotFirstTurn(int iPlayer) + public final void setPlayerWhoGotFirstTurn(String playerName) { - playerGotFirstTurn = iPlayer; + playerGotFirstTurn = playerName; } public void notifyNextTurn() { diff --git a/src/main/java/forge/game/GameType.java b/src/main/java/forge/game/GameType.java index a7dfb4d4566..187bcaf7139 100644 --- a/src/main/java/forge/game/GameType.java +++ b/src/main/java/forge/game/GameType.java @@ -7,6 +7,7 @@ public enum GameType { Constructed(false), Sealed(true), Draft(true), + Commander(false), Quest(true); private final boolean bLimited; diff --git a/src/main/java/forge/game/PlayerIndex.java b/src/main/java/forge/game/PlayerIndex.java deleted file mode 100644 index 8a7b054bb68..00000000000 --- a/src/main/java/forge/game/PlayerIndex.java +++ /dev/null @@ -1,8 +0,0 @@ -package forge.game; - -public interface PlayerIndex { - int UNDEFINED = Integer.MIN_VALUE; - int DRAW = -1; - int HUMAN = 0; - int AI = 1; -} diff --git a/src/main/java/forge/gui/input/Input_Mulligan.java b/src/main/java/forge/gui/input/Input_Mulligan.java index c710b46d946..a83e5a8b6c8 100644 --- a/src/main/java/forge/gui/input/Input_Mulligan.java +++ b/src/main/java/forge/gui/input/Input_Mulligan.java @@ -16,7 +16,6 @@ import forge.Player; import forge.card.abilityFactory.AbilityFactory; import forge.card.spellability.SpellAbility; import forge.game.GamePlayerRating; -import forge.game.PlayerIndex; import forge.quest.data.QuestData; /** @@ -68,9 +67,9 @@ public class Input_Mulligan extends Input { /** {@inheritDoc} */ @Override public final void selectButtonCancel() { - GamePlayerRating humanRating = AllZone.getGameInfo().getPlayerRating(PlayerIndex.HUMAN); Player humanPlayer = AllZone.getHumanPlayer(); - + GamePlayerRating humanRating = AllZone.getGameInfo().getPlayerRating(humanPlayer.getName()); + int newHand = doMulligan(humanPlayer, humanRating); QuestData quest = AllZone.getQuestData(); @@ -90,7 +89,7 @@ public class Input_Mulligan extends Input { final void end() { //Computer mulligan Player aiPlayer = AllZone.getComputerPlayer(); - GamePlayerRating aiRating = AllZone.getGameInfo().getPlayerRating(PlayerIndex.AI); + GamePlayerRating aiRating = AllZone.getGameInfo().getPlayerRating(aiPlayer.getName()); boolean aiTakesMulligan = true; //Computer mulligans if there are no cards with converted mana cost of 0 in its hand diff --git a/src/main/java/forge/model/FGameState.java b/src/main/java/forge/model/FGameState.java index 037a870fb42..4e20e46c4ff 100644 --- a/src/main/java/forge/model/FGameState.java +++ b/src/main/java/forge/model/FGameState.java @@ -14,14 +14,19 @@ import forge.Player; import forge.PlayerZone; import forge.StaticEffects; import forge.Upkeep; +import forge.Constant.Zone; import forge.card.trigger.TriggerHandler; +import forge.game.GameSummary; /** * Represents the Forge Game State. */ public class FGameState { - private Player humanPlayer = new HumanPlayer("Human"); - private Player computerPlayer = new AIPlayer("Computer"); + public static final String HUMAN_PLAYER_NAME = "Human"; + public static final String AI_PLAYER_NAME = "Computer"; + + private Player humanPlayer = new HumanPlayer(HUMAN_PLAYER_NAME); + private Player computerPlayer = new AIPlayer(AI_PLAYER_NAME); private EndOfTurn endOfTurn = new EndOfTurn(); private EndOfCombat endOfCombat = new EndOfCombat(); private Upkeep upkeep = new Upkeep(); @@ -36,6 +41,7 @@ public class FGameState { private PlayerZone stackZone = new DefaultPlayerZone(Constant.Zone.Stack, null); private long timestamp = 0; + private GameSummary gameInfo; /** * Constructor. @@ -264,4 +270,32 @@ public class FGameState { this.timestamp = timestamp0; } + + public GameSummary getGameInfo() { + return gameInfo; + } + + + /** + * Call this each time you start a new game, ok? + */ + public void newGameCleanup() { + gameInfo = new GameSummary(humanPlayer.getName(), computerPlayer.getName()); + + getHumanPlayer().reset(); + getComputerPlayer().reset(); + + getPhase().reset(); + getStack().reset(); + getCombat().reset(); + + for (Player p : getPlayers()) { + for(Zone z : Player.ALL_ZONES) { + p.getZone(z).reset(); + } + } + + getStaticEffects().reset(); + } + } diff --git a/src/main/java/forge/quest/data/QuestMatchState.java b/src/main/java/forge/quest/data/QuestMatchState.java index e94366cdb34..659d9fca1e3 100644 --- a/src/main/java/forge/quest/data/QuestMatchState.java +++ b/src/main/java/forge/quest/data/QuestMatchState.java @@ -1,7 +1,9 @@ package forge.quest.data; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import forge.game.GameSummary; @@ -33,43 +35,41 @@ public class QuestMatchState { return gamesPlayed.size(); } - public final boolean hasHumanWonLastGame() { + public final boolean hasWonLastGame(String playerName) { int iLastGame = gamesPlayed.size() - 1; - return iLastGame >= 0 ? gamesPlayed.get(iLastGame).isHumanWinner() : false; + return iLastGame >= 0 ? gamesPlayed.get(iLastGame).isWinner(playerName) : false; } public final boolean isMatchOver() { - int winsHuman = 0; - int winsAI = 0; int totalGames = 0; + Map winsCount = new HashMap(); for (GameSummary game : gamesPlayed) { - if (game.isAIWinner()) { winsAI++; } - if (game.isHumanWinner()) { winsHuman++; } + String winner = game.getWinner(); + Integer boxedWins = winsCount.get(winner); + int wins = boxedWins == null ? 0 : boxedWins.intValue(); + winsCount.put(winner, wins + 1); totalGames++; } - - return winsAI >= MIN_GAMES_TO_WIN_MATCH || winsHuman >= MIN_GAMES_TO_WIN_MATCH || totalGames >= GAMES_PER_MATCH; - } - - public final int getGamesCountWonByHuman() { - int winsHuman = 0; - for (GameSummary game : gamesPlayed) { - if (game.isHumanWinner()) { winsHuman++; } + + int maxWins = 0; + for (Integer win : winsCount.values()) { + maxWins = Math.max(maxWins, win); } - return winsHuman; + + return maxWins >= MIN_GAMES_TO_WIN_MATCH || totalGames >= GAMES_PER_MATCH; } - public final int getGamesCountLostByHuman() { - int lossHuman = 0; + public final int countGamesWonBy(String name) { + int wins = 0; for (GameSummary game : gamesPlayed) { - if (!game.isHumanWinner()) { lossHuman++; } + if (game.isWinner(name)) { wins++; } } - return lossHuman; + return wins; } - public final boolean isMatchWonByHuman() { - return getGamesCountWonByHuman() >= MIN_GAMES_TO_WIN_MATCH; + public final boolean isMatchWonBy(String name) { + return countGamesWonBy(name) >= MIN_GAMES_TO_WIN_MATCH; } public final void reset() { diff --git a/src/main/java/forge/quest/data/QuestUtilRewards.java b/src/main/java/forge/quest/data/QuestUtilRewards.java index a45518ee8e6..328b1bc8ec5 100644 --- a/src/main/java/forge/quest/data/QuestUtilRewards.java +++ b/src/main/java/forge/quest/data/QuestUtilRewards.java @@ -1,10 +1,11 @@ package forge.quest.data; +import forge.AllZone; import forge.MyRandom; +import forge.Player; import forge.game.GameLossReason; import forge.game.GamePlayerRating; import forge.game.GameSummary; -import forge.game.PlayerIndex; /** * Helper class to deal with rewards given in quest. @@ -47,14 +48,16 @@ public class QuestUtilRewards { + (QuestPreferences.getMatchRewardTotalWins() * q.getWin())); boolean hasNeverLost = true; + Player computer = AllZone.getComputerPlayer(); for (GameSummary game : matchState.getGamesPlayed()) { - if (game.isAIWinner()) { - hasNeverLost = true; + + if (game.isWinner(computer.getName())) { + hasNeverLost = false; continue; // no rewards for losing a game } - - GamePlayerRating aiRating = game.getPlayerRating(PlayerIndex.AI); - GamePlayerRating humanRating = game.getPlayerRating(PlayerIndex.HUMAN); + + GamePlayerRating aiRating = game.getPlayerRating(computer.getName()); + GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName()); GameLossReason whyAiLost = aiRating.getLossReason(); creds += getCreditsRewardForAltWin(whyAiLost);