diff --git a/.gitattributes b/.gitattributes index 11716227c2c..82318f13b2b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12577,6 +12577,7 @@ src/main/java/forge/card/trigger/package-info.java svneol=native#text/plain src/main/java/forge/control/ControlBazaarUI.java -text src/main/java/forge/control/FControl.java -text src/main/java/forge/control/KeyboardShortcuts.java -text +src/main/java/forge/control/Lobby.java -text src/main/java/forge/control/RestartUtil.java -text src/main/java/forge/control/bazaar/ControlStall.java -text src/main/java/forge/control/bazaar/package-info.java svneol=native#text/plain @@ -12626,11 +12627,12 @@ src/main/java/forge/game/GameEndReason.java -text src/main/java/forge/game/GameFormat.java -text src/main/java/forge/game/GameLossReason.java -text src/main/java/forge/game/GameNew.java -text -src/main/java/forge/game/GamePlayerRating.java -text +src/main/java/forge/game/GameOutcome.java -text src/main/java/forge/game/GameState.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/PlayerStartsGame.java -text +src/main/java/forge/game/MatchController.java -text +src/main/java/forge/game/MatchStartHelper.java -text +src/main/java/forge/game/PlayerStartConditions.java -text src/main/java/forge/game/limited/BoosterDeck.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 @@ -12670,7 +12672,10 @@ src/main/java/forge/game/player/ComputerUtil.java svneol=native#text/plain src/main/java/forge/game/player/ComputerUtilAttack.java svneol=native#text/plain src/main/java/forge/game/player/ComputerUtilBlock.java svneol=native#text/plain src/main/java/forge/game/player/HumanPlayer.java svneol=native#text/plain +src/main/java/forge/game/player/LobbyPlayer.java -text src/main/java/forge/game/player/Player.java svneol=native#text/plain +src/main/java/forge/game/player/PlayerOutcome.java -text +src/main/java/forge/game/player/PlayerStatistics.java -text src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain src/main/java/forge/game/player/PlayerUtil.java svneol=native#text/plain src/main/java/forge/game/player/package-info.java svneol=native#text/plain @@ -12892,7 +12897,6 @@ src/main/java/forge/item/PreconDeck.java -text src/main/java/forge/item/TournamentPack.java -text src/main/java/forge/item/package-info.java -text src/main/java/forge/model/BuildInfo.java -text -src/main/java/forge/model/FMatchState.java svneol=native#text/plain src/main/java/forge/model/FModel.java svneol=native#text/plain src/main/java/forge/model/MultipleForgeJarsFoundError.java -text src/main/java/forge/model/package-info.java svneol=native#text/plain diff --git a/src/main/java/forge/AllZone.java b/src/main/java/forge/AllZone.java index 101b366553e..c3f0c73d4ed 100644 --- a/src/main/java/forge/AllZone.java +++ b/src/main/java/forge/AllZone.java @@ -17,8 +17,6 @@ */ package forge; -import java.util.List; - import forge.card.cardfactory.CardFactory; import forge.card.cardfactory.CardFactoryInterface; import forge.card.replacement.ReplacementHandler; @@ -29,13 +27,11 @@ import forge.game.limited.GauntletMini; import forge.game.phase.Combat; import forge.game.phase.EndOfTurn; import forge.game.player.Player; -import forge.game.player.PlayerType; import forge.game.zone.MagicStack; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.properties.ForgeProps; import forge.properties.NewConstants; -import forge.util.Aggregates; /** @@ -75,40 +71,6 @@ public final class AllZone { // shared between Input_Attack, Input_Block, Input_CombatDamage , // InputState_Computer - /** - *

- * getHumanPlayer. - *

- * - * Will eventually be marked deprecated. - * - * @return a {@link forge.game.player.Player} object. - * @since 1.0.15 - */ - @Deprecated - public static Player getHumanPlayer() { - if (Singletons.getModel() == null) - return null; - - return Aggregates.firstFieldEquals(Singletons.getModel().getGameState().getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.HUMAN); - } - - /** - *

- * getComputerPlayer. - *

- * - * Will eventually be marked deprecated. - * - * @return a {@link forge.game.player.Player} object. - * @since 1.0.15 - */ - @Deprecated - public static Player getComputerPlayer() { - List players = Singletons.getModel().getGameState().getPlayers(); - return Aggregates.firstFieldEquals(players, Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER); - } - /** *

* getGauntletData. diff --git a/src/main/java/forge/AllZoneUtil.java b/src/main/java/forge/AllZoneUtil.java index 11894862138..d1b5e56785d 100644 --- a/src/main/java/forge/AllZoneUtil.java +++ b/src/main/java/forge/AllZoneUtil.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.CardPredicates.Presets; import forge.game.player.Player; @@ -47,33 +48,24 @@ public abstract class AllZoneUtil { * @return a List with all cards currently in a graveyard */ public static List getCardsIn(final ZoneType zone) { - final List cards = new ArrayList(); - getCardsIn(zone, cards); - return cards; - } - - private static void getCardsIn(final ZoneType zone, final List cards) { if (zone == ZoneType.Stack) { - cards.addAll(AllZone.getStackZone().getCards()); + return AllZone.getStackZone().getCards(); } else { + List cards = null; for (final Player p : Singletons.getModel().getGameState().getPlayers()) { - cards.addAll(p.getZone(zone).getCards()); + if ( cards == null ) + cards = p.getZone(zone).getCards(); + else + cards.addAll(p.getZone(zone).getCards()); } + return cards; } } public static List getCardsIn(final Iterable zones) { final List cards = new ArrayList(); for (final ZoneType z : zones) { - getCardsIn(z, cards); - } - return cards; - } - - public static List getCardsIn(final ZoneType[] zones) { - final List cards = new ArrayList(); - for (final ZoneType z : zones) { - getCardsIn(z, cards); + cards.addAll(getCardsIn(z)); } return cards; } @@ -182,10 +174,9 @@ public abstract class AllZoneUtil { * @return true is the card is in play, false otherwise */ public static boolean isCardInPlay(final String cardName) { - for (Card card : AllZoneUtil.getCardsIn(ZoneType.Battlefield)) { - if (card.getName().equals(cardName)) { + for (final Player p : Singletons.getModel().getGameState().getPlayers()) { + if (isCardInPlay(cardName, p)) return true; - } } return false; } @@ -200,12 +191,7 @@ public abstract class AllZoneUtil { * @return true if that player has that card in play, false otherwise */ public static boolean isCardInPlay(final String cardName, final Player player) { - for (Card card : player.getCardsIn(ZoneType.Battlefield)) { - if (card.getName().equals(cardName)) { - return true; - } - } - return false; + return Iterables.any(player.getZone(ZoneType.Battlefield), CardPredicates.nameEquals(cardName)); } // ////////////// getting all cards of a given color diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index ab7b9a9f931..99008d8acbc 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -26,6 +26,7 @@ import java.util.List; import javax.swing.JFrame; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.card.abilityfactory.AbilityFactory; import forge.card.abilityfactory.AbilityFactoryAttach; @@ -51,8 +52,8 @@ import forge.card.trigger.TriggerType; import forge.control.input.InputPayManaCost; import forge.control.input.InputPayManaCostUtil; import forge.game.GameEndReason; -import forge.game.GameSummary; -import forge.game.phase.PhaseHandler; +import forge.game.GameLossReason; +import forge.game.GameState; import forge.game.player.ComputerUtil; import forge.game.player.Player; import forge.game.zone.PlayerZone; @@ -896,54 +897,43 @@ public class GameAction { * * @return a boolean. */ - public final boolean checkEndGameState() { + public final boolean checkEndGameState(final GameState game) { // if game is already over return true - if (Singletons.getModel().getGameState().isGameOver()) { + if (game.isGameOver()) { return true; } - // Win / Lose - final GameSummary game = Singletons.getModel().getGameSummary(); - boolean humanWins = false; - boolean computerWins = false; - final Player computer = AllZone.getComputerPlayer(); - final Player human = AllZone.getHumanPlayer(); - // Winning Conditions can be worth more than losing conditions - if (human.hasWon() || computer.hasLost()) { - humanWins = true; - - if (human.getAltWin()) { - game.end(GameEndReason.WinsGameSpellEffect, human.getName(), human.getWinConditionSource()); - } else { - game.end(GameEndReason.AllOpponentsLost, human.getName(), null); - } + GameEndReason reason = null; + // award loses as SBE + for (Player p : game.getPlayers() ) { + p.checkLoseCondition(); // this will set appropriate outcomes } - - if (computer.hasWon() || human.hasLost()) { - if (humanWins) { - // both players won/lost at the same time. - game.end(GameEndReason.Draw, null, null); - } else { - computerWins = true; - - if (computer.getAltWin()) { - game.end(GameEndReason.WinsGameSpellEffect, computer.getName(), computer.getWinConditionSource()); - } else { - game.end(GameEndReason.AllOpponentsLost, computer.getName(), null); + + // Has anyone won by spelleffect? + for (Player p : game.getPlayers() ) { + if( p.hasWon() ) { // then the rest have lost! + reason = GameEndReason.WinsGameSpellEffect; + for (Player pl : game.getPlayers() ) { + if( !pl.equals(p) ) + if ( !pl.loseConditionMet(GameLossReason.OpponentWon, p.getOutcome().altWinSourceName) ) + reason = null; // they cannot lose! } - + break; } } - - final boolean isGameDone = humanWins || computerWins; - if (isGameDone) { - Singletons.getModel().getGameState().setGameOver(true); - game.getPlayerRating(computer.getName()).setLossReason(computer.getLossState(), computer.getLossConditionSource()); - game.getPlayerRating(human.getName()).setLossReason(human.getLossState(), human.getLossConditionSource()); - Singletons.getModel().getMatchState().addGamePlayed(game); + + // still unclear why this has not caught me conceding + if ( reason == null && Iterables.size(Iterables.filter(game.getPlayers(), Player.Predicates.NOT_LOST)) == 1 ) + { + reason = GameEndReason.AllOpponentsLost; + } + + if (reason != null) { + game.setGameOver(); + Singletons.getModel().getMatch().addGamePlayed(reason, game); } - return isGameDone; + return reason != null; } /** */ @@ -1015,7 +1005,7 @@ public class GameAction { return; } - if (this.checkEndGameState()) { + if (this.checkEndGameState(Singletons.getModel().getGameState())) { // Clear Simultaneous triggers at the end of the game new ViewWinLose(); Singletons.getModel().getGameState().getStack().clearSimultaneousStack(); @@ -1031,9 +1021,6 @@ public class GameAction { boolean checkAgain = false; - AllZone.getHumanPlayer().setMaxHandSize(7); - AllZone.getComputerPlayer().setMaxHandSize(7); - this.checkStaticAbilities(); final HashMap runParams = new HashMap(); @@ -1693,7 +1680,7 @@ public class GameAction { originalCard.setXManaCostPaid(0); } - if (PhaseHandler.getGameBegins() != 1 || sa.isTrigger()) { + if (Singletons.getModel().getGameState() != null || sa.isTrigger()) { return manaCost; } diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 86e946ddb89..d1ceae20863 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -29,7 +29,6 @@ import forge.CardUtil; import forge.Singletons; import forge.card.CardRules; import forge.card.cost.Cost; -import forge.card.mana.ManaCost; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; diff --git a/src/main/java/forge/card/mana/ManaPool.java b/src/main/java/forge/card/mana/ManaPool.java index eabf5788d1c..b12e03c4cfe 100644 --- a/src/main/java/forge/card/mana/ManaPool.java +++ b/src/main/java/forge/card/mana/ManaPool.java @@ -64,7 +64,6 @@ public class ManaPool { */ public ManaPool(final Player player) { owner = player; - owner.updateObservers(); clearPool(); ManaPool.MAP.put(Constant.Color.WHITE, 0); ManaPool.MAP.put(Constant.Color.BLUE, 1); diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 38350768f71..aa76bdce84c 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -35,6 +35,7 @@ import forge.AllZone; import forge.Singletons; import forge.control.KeyboardShortcuts.Shortcut; import forge.game.player.Player; +import forge.game.player.PlayerType; import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.framework.SOverflowUtil; @@ -49,6 +50,7 @@ import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.quest.data.QuestPreferences.QPref; import forge.quest.io.QuestDataIO; +import forge.util.Aggregates; import forge.view.FView; /** @@ -273,6 +275,20 @@ public enum FControl { /** @return {@link forge.game.player.Player} */ public Player getPlayer() { - return AllZone.getHumanPlayer(); + if (Singletons.getModel() == null) + return null; + + return Aggregates.firstFieldEquals(Singletons.getModel().getGameState().getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.HUMAN); + } + + /** + * TODO: Write javadoc for this method. + * @return + */ + private Lobby lobby = null; + public Lobby getLobby() { + if( lobby == null ) + lobby = new Lobby(); + return lobby; } } diff --git a/src/main/java/forge/control/Lobby.java b/src/main/java/forge/control/Lobby.java new file mode 100644 index 00000000000..62047d4f9c3 --- /dev/null +++ b/src/main/java/forge/control/Lobby.java @@ -0,0 +1,102 @@ +package forge.control; + +import java.util.Random; + +import forge.game.player.LobbyPlayer; +import forge.game.player.PlayerType; +import forge.util.MyRandom; + +/** + * TODO: Write javadoc for this type. + * + */ +public class Lobby { + + + private final String[] opponentNames = new String[] { + "Abigail", "Ada", "Adeline", "Adriana", "Agatha", "Agnes", "Aileen", "Alba", "Alcyon", + "Alethea", "Alice", "Alicia", "Alison", "Amanda", "Amelia", "Amy", "Andrea", "Angelina", + "Anita", "Ann", "Annabel", "Anne", "Audrey", "Barbara", "Belinda", "Bernice", "Bertha", + "Bonnie", "Brenda", "Bridget", "Bunny", "Carmen", "Carol", "Catherine", "Cheryl", + "Christine", "Cinderalla", "Claire", "Clarice", "Claudia", "Constance", "Cora", + "Corinne", "Cnythia", "Daisy", "Daphne", "Dawn", "Deborah", "Diana", "Dolly", "Dora", + "Doreen", "Doris", "Dorothy", "Eileen", "Elaine", "Elizabeth", "Emily", "Emma", "Ethel", + "Evelyn", "Fiona", "Florence", "Frances", "Geraldine", "Gertrude", "Gladys", "Gloria", + "Grace", "Greta", "Harriet", "Hazel", "Helen", "Hilda", "Ida", "Ingrid", "Irene", + "Isabel", "Jacinta", "Jackie", "Jane", "Janet", "Janice", "Jennifer", "Jessie", "Joan", + "Jocelyn", "Josephine", "Joyce", "Judith", "Julia", "Juliana", "Karina", "Kathleen", + "Laura", "Lilian", "Lily", "Linda", "Lisa", "Lilita", "Lora", "Lorna", "Lucy", "Lydia", + "Mabel", "Madeline", "Maggie", "Maria", "Mariam", "Marilyn", "Mary", "Matilda", "Mavis", + "Melanie", "Melinda", "Melody", "Michelle", "Mildred", "Molly", "Mona", "Monica", + "Nancy", "Nora", "Norma", "Olga", "Pamela", "Patricia", "Paula", "Pauline", "Pearl", + "Peggy", "Penny", "Phoebe", "Phyllis", "Polly", "Priscilla", "Rachel", "Rebecca", + "Rita", "Rosa", "Rosalind", "Rose", "Rosemary", "Rowena", "Ruby", "Sally", "Samantha", + "Sarah", "Selina", "Sharon", "Sheila", "Shirley", "Sonya", "Stella", "Sue", "Susan", + "Sylvia", "Tina", "Tracy", "Ursula", "Valentine", "Valerie", "Vanessa", "Veronica", + "Victoria", "Violet", "Vivian", "Wendy", "Winnie", "Yvonne", "Aaron", "Abraham", "Adam", + "Adrain", "Alain", "Alan", "Alban", "Albert", "Alec", "Alexander", "Alfonso", "Alfred", + "Allan", "Allen", "Alonso", "Aloysius", "Alphonso", "Alvin", "Andrew", "Andy", "Amadeus", + "Amselm", "Anthony", "Arnold", "Augusta", "Austin", "Barnaby", "Benedict", "Benjamin", + "Bertie", "Bertram", "Bill", "Bob", "Boris", "Brady", "Brian", "Bruce", "Burt", "Byron", + "Calvin", "Carl", "Carter", "Casey", "Cecil", "Charles", "Christian", "Christopher", + "Clarence", "Clement", "Colin", "Conan", "Dalton", "Damian", "Daniel", "David", "Denis", + "Derek", "Desmond", "Dick", "Dominic", "Donald", "Douglas", "Duncan", "Edmund", + "Edward", "Ellen", "Elton", "Elvis", "Eric", "Eugene", "Felix", "Francis", "Frank", + "Frederick", "Gary", "Geoffrey", "George", "Gerald", "Gerry", "Gordon", "Hamish", + "Hardy", "Harold", "Harry", "Henry", "Herbert", "Ignatius", "Jack", "James", "Jeffrey", + "Jim", "Joe", "John", "Joseph", "Karl", "Keith", "Kenneth", "Kevin", "Larry", "Lawrence", + "Leonard", "Lionel", "Louis", "Lucas", "Malcolm", "Mark", "Martin", "Mathew", "Maurice", + "Max", "Melvin", "Michael", "Milton", "Morgan", "Morris", "Murphy", "Neville", + "Nicholas", "Noel", "Norman", "Oliver", "Oscar", "Patrick", "Paul", "Perkin", "Peter", + "Philip", "Ralph", "Randy", "Raymond", "Richard", "Ricky", "Robert", "Robin", "Rodney", + "Roger", "Roland", "Ronald", "Roy", "Sam", "Sebastian", "Simon", "Stanley", "Stephen", + "Stuart", "Terence", "Thomas", "Tim", "Tom", "Tony", "Victor", "Vincent", "Wallace", + "Walter", "Wilfred", "William", "Winston" + }; + + /** + * TODO: Write javadoc for this method. + * @param human + * @return + */ + public LobbyPlayer findLocalPlayer(PlayerType type, String name) { + + + return new LobbyPlayer(type, name); + } + + /** + * TODO: Write javadoc for this method. + * @param human + * @return + */ + public LobbyPlayer findLocalPlayer(PlayerType type) { + if ( type == PlayerType.HUMAN ) + return new LobbyPlayer(type, "Human"); // need to get name! + + + return findLocalPlayer(type, getRandomName()); + } + + /** + * TODO: Write javadoc for this method. + * @param nextInt + * @return + */ + private String getRandomName() { + Random my = MyRandom.getRandom(); + return opponentNames[my.nextInt(opponentNames.length)]; + + } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public LobbyPlayer getQuestPlayer() { + return new LobbyPlayer(PlayerType.HUMAN, "Human"); // need to get name! + } + + + +} diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index 11dfc092d4e..b2c3130ccfb 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -21,6 +21,7 @@ import java.util.LinkedList; import java.util.Stack; import forge.AllZone; +import forge.Singletons; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.ComputerAIInput; @@ -198,7 +199,7 @@ public class InputControl extends MyObservable implements java.io.Serializable { return this.input; } - if ((PhaseHandler.getGameBegins() != 0) && handler.doPhaseEffects()) { + if (Singletons.getModel().getGameState() != null && handler.doPhaseEffects()) { // Handle begin phase stuff, then start back from the top handler.handleBeginPhase(); return this.updateInput(); @@ -215,7 +216,7 @@ public class InputControl extends MyObservable implements java.io.Serializable { this.model.getGameState().getStack().freezeStack(); if (playerTurn.isHuman() && !handler.getAutoPass()) { - AllZone.getCombat().initiatePossibleDefenders(AllZone.getComputerPlayer()); + AllZone.getCombat().initiatePossibleDefenders(playerTurn.getOpponent()); return new InputAttack(); } } else if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS) { diff --git a/src/main/java/forge/control/input/InputMulligan.java b/src/main/java/forge/control/input/InputMulligan.java index a93500275e7..10f38d83230 100644 --- a/src/main/java/forge/control/input/InputMulligan.java +++ b/src/main/java/forge/control/input/InputMulligan.java @@ -30,8 +30,6 @@ import forge.GameActionUtil; import forge.Singletons; import forge.card.abilityfactory.AbilityFactory; import forge.card.spellability.SpellAbility; -import forge.game.GamePlayerRating; -import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseUtil; import forge.game.player.ComputerUtil; import forge.game.player.Player; @@ -41,8 +39,6 @@ import forge.gui.framework.SDisplayUtil; import forge.gui.match.CMatchUI; import forge.gui.match.VMatchUI; import forge.gui.match.views.VMessage; -import forge.quest.QuestController; -import forge.quest.bazaar.QuestItemType; import forge.view.ButtonUtil; /** *

@@ -56,7 +52,6 @@ public class InputMulligan extends Input { /** Constant serialVersionUID=-8112954303001155622L. */ private static final long serialVersionUID = -8112954303001155622L; - private static final int MAGIC_NUMBER_OF_SHUFFLES = 100; private static final int AI_MULLIGAN_THRESHOLD = 5; /** {@inheritDoc} */ @@ -67,7 +62,7 @@ public class InputMulligan extends Input { VMatchUI.SINGLETON_INSTANCE.getBtnCancel().setText("Yes"); final String str = - (Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn().equals(AllZone.getHumanPlayer()) + (Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn().equals(Singletons.getControl().getPlayer()) ? "You're going first. " : "The computer is going first. "); CMatchUI.SINGLETON_INSTANCE.showMessage(str + "Do you want to Mulligan?"); } @@ -78,82 +73,48 @@ public class InputMulligan extends Input { this.end(); } - /** - * - * TODO Write javadoc for this method. - * - * @param player - * a Player object - * @param playerRating - * a GamePlayerRating object - * @return an int - */ - public final int doMulligan(final Player player, final GamePlayerRating playerRating) { - final List hand = player.getCardsIn(ZoneType.Hand); - for (final Card c : hand) { - Singletons.getModel().getGameAction().moveToLibrary(c); - } - for (int i = 0; i < InputMulligan.MAGIC_NUMBER_OF_SHUFFLES; i++) { - player.shuffle(); - } - final int newHand = hand.size() - 1; - for (int i = 0; i < newHand; i++) { - player.drawCard(); - } - AllZone.getGameLog().add("Mulligan", player + " has mulliganed down to " + newHand + " cards.", 0); - playerRating.notifyHasMulliganed(); - playerRating.notifyOpeningHandSize(newHand); - return newHand; - } + /** {@inheritDoc} */ @Override public final void selectButtonCancel() { - final Player humanPlayer = AllZone.getHumanPlayer(); - final GamePlayerRating humanRating = Singletons.getModel().getGameSummary().getPlayerRating(humanPlayer.getName()); + final Player humanPlayer = Singletons.getControl().getPlayer(); + - final int newHand = this.doMulligan(humanPlayer, humanRating); - - final QuestController quest = Singletons.getModel().getQuest(); - if (quest.isLoaded() && quest.getAssets().hasItem(QuestItemType.SLEIGHT) && (humanRating.getMulliganCount() == 1)) { - AllZone.getHumanPlayer().drawCard(); - humanRating.notifyOpeningHandSize(newHand + 1); - } + final int newHand = humanPlayer.doMulligan(); if (newHand == 0) { this.end(); } } // selectButtonOK() - /** - *

- * end. - *

- */ final void end() { // Computer mulligan - final GameAction ga = Singletons.getModel().getGameAction(); - final Player aiPlayer = AllZone.getComputerPlayer(); - final GamePlayerRating aiRating = Singletons.getModel().getGameSummary().getPlayerRating(aiPlayer.getName()); - boolean aiTakesMulligan = true; - // Computer mulligans if there are no cards with converted mana cost of - // 0 in its hand - while (aiTakesMulligan) { - - final List handList = aiPlayer.getCardsIn(ZoneType.Hand); - final boolean hasLittleCmc0Cards = CardLists.getValidCards(handList, "Card.cmcEQ0", aiPlayer, null).size() < 2; - aiTakesMulligan = (handList.size() > InputMulligan.AI_MULLIGAN_THRESHOLD) && hasLittleCmc0Cards; - - if (aiTakesMulligan) { - this.doMulligan(aiPlayer, aiRating); + for (Player ai : Singletons.getModel().getGameState().getPlayers()) { + if ( ai.isHuman() ) continue; + + boolean aiTakesMulligan = true; + + // Computer mulligans if there are no cards with converted mana cost of + // 0 in its hand + while (aiTakesMulligan) { + + final List handList = ai.getCardsIn(ZoneType.Hand); + final boolean hasLittleCmc0Cards = CardLists.getValidCards(handList, "Card.cmcEQ0", ai, null).size() < 2; + aiTakesMulligan = (handList.size() > InputMulligan.AI_MULLIGAN_THRESHOLD) && hasLittleCmc0Cards; + + if (aiTakesMulligan) { + ai.doMulligan(); + } } } // Human Leylines & Chancellors ButtonUtil.reset(); final AbilityFactory af = new AbilityFactory(); - + + final GameAction ga = Singletons.getModel().getGameAction(); for (Player p : Singletons.getModel().getGameState().getPlayers()) { final List openingHand = p.getCardsIn(ZoneType.Hand); @@ -210,7 +171,7 @@ public class InputMulligan extends Input { //ga.checkStateEffects(); ga.checkStateEffects(); - PhaseHandler.setGameBegins(1); + AllZone.getGameLog().add("Turn", "Turn " + Singletons.getModel().getGameState().getPhaseHandler().getTurn() + " (" + Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn() + ")", diff --git a/src/main/java/forge/control/input/InputPassPriority.java b/src/main/java/forge/control/input/InputPassPriority.java index 1a77be36114..a024aad2937 100644 --- a/src/main/java/forge/control/input/InputPassPriority.java +++ b/src/main/java/forge/control/input/InputPassPriority.java @@ -86,7 +86,7 @@ public class InputPassPriority extends Input implements java.io.Serializable { @Override public final void selectCard(final Card card, final PlayerZone zone) { if (Singletons.getModel().getGameAction().playCard(card)) { - Singletons.getModel().getGameState().getPhaseHandler().setPriority(AllZone.getHumanPlayer()); + Singletons.getModel().getGameState().getPhaseHandler().setPriority(Singletons.getControl().getPlayer()); } else { SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE); diff --git a/src/main/java/forge/control/input/InputPayManaCost.java b/src/main/java/forge/control/input/InputPayManaCost.java index 74dbbdcc7c3..6970a12cc10 100644 --- a/src/main/java/forge/control/input/InputPayManaCost.java +++ b/src/main/java/forge/control/input/InputPayManaCost.java @@ -23,7 +23,6 @@ import forge.Singletons; import forge.card.mana.ManaCost; import forge.card.spellability.SpellAbility; import forge.card.trigger.TriggerType; -import forge.game.phase.PhaseHandler; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; @@ -76,7 +75,7 @@ public class InputPayManaCost extends InputMana { this.spell = sa; - if (PhaseHandler.getGameBegins() == 1) { + if (Singletons.getModel().getGameState() != null) { if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) { if (this.spell.getAfterPayMana() != null) { this.stopSetNext(this.spell.getAfterPayMana()); @@ -121,7 +120,7 @@ public class InputPayManaCost extends InputMana { this.spell = sa; - if (PhaseHandler.getGameBegins() == 1) { + if (Singletons.getModel().getGameState() != null ) { if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) { if (this.spell.getAfterPayMana() != null) { this.stopSetNext(this.spell.getAfterPayMana()); @@ -266,8 +265,9 @@ public class InputPayManaCost extends InputMana { } this.resetManaCost(); - AllZone.getHumanPlayer().getManaPool().refundManaPaid(this.spell, true); - AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); // DO + Player human = Singletons.getControl().getPlayer(); + human.getManaPool().refundManaPaid(this.spell, true); + human.getZone(ZoneType.Battlefield).updateObservers(); // DO this.stop(); } diff --git a/src/main/java/forge/control/input/InputPayManaCostAbility.java b/src/main/java/forge/control/input/InputPayManaCostAbility.java index 346458d9607..a2cb17d2dd8 100644 --- a/src/main/java/forge/control/input/InputPayManaCostAbility.java +++ b/src/main/java/forge/control/input/InputPayManaCostAbility.java @@ -17,7 +17,6 @@ */ package forge.control.input; -import forge.AllZone; import forge.Card; import forge.Command; import forge.Singletons; @@ -202,7 +201,7 @@ public class InputPayManaCostAbility extends InputMana { public final void selectButtonCancel() { this.unpaidCommand.execute(); this.resetManaCost(); - AllZone.getHumanPlayer().getManaPool().refundManaPaid(this.fakeAbility, true); + Singletons.getControl().getPlayer().getManaPool().refundManaPaid(this.fakeAbility, true); this.stop(); } diff --git a/src/main/java/forge/control/input/InputPayManaCostUtil.java b/src/main/java/forge/control/input/InputPayManaCostUtil.java index 51137649c4e..676a429d04c 100644 --- a/src/main/java/forge/control/input/InputPayManaCostUtil.java +++ b/src/main/java/forge/control/input/InputPayManaCostUtil.java @@ -37,7 +37,6 @@ import forge.card.mana.ManaPool; import forge.card.spellability.AbilityMana; import forge.card.spellability.SpellAbility; import forge.card.trigger.TriggerType; -import forge.game.phase.PhaseHandler; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; @@ -418,7 +417,7 @@ public class InputPayManaCostUtil { public void selectButtonCancel() { this.stop(); payment.cancelCost(); - AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); + Singletons.getControl().getPlayer().getZone(ZoneType.Battlefield).updateObservers(); } @Override @@ -470,7 +469,7 @@ public class InputPayManaCostUtil { final int manaToAdd) { final ManaCost manaCost; - if (PhaseHandler.getGameBegins() == 1) { + if (Singletons.getModel().getGameState() != null ) { final String mana = costMana.getManaToPay(); manaCost = new ManaCost(mana); manaCost.increaseColorlessMana(manaToAdd); @@ -574,7 +573,7 @@ public class InputPayManaCostUtil { this.stop(); this.resetManaCost(); payment.cancelCost(); - AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); + Singletons.getControl().getPlayer().getZone(ZoneType.Battlefield).updateObservers(); } @Override diff --git a/src/main/java/forge/control/input/InputPayReturnCost.java b/src/main/java/forge/control/input/InputPayReturnCost.java index 749855c6e3f..215733e685d 100644 --- a/src/main/java/forge/control/input/InputPayReturnCost.java +++ b/src/main/java/forge/control/input/InputPayReturnCost.java @@ -19,7 +19,6 @@ package forge.control.input; import java.util.List; -import forge.AllZone; import forge.Card; import forge.CardLists; @@ -77,7 +76,7 @@ public class InputPayReturnCost extends Input { this.ability = sa; this.returnCost = cost; - this.choiceList = CardLists.getValidCards(AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), AllZone.getHumanPlayer(), source); + this.choiceList = CardLists.getValidCards(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), Singletons.getControl().getPlayer(), source); String amountString = cost.getAmount(); this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) : CardFactoryUtil.xCount(source, source.getSVar(amountString)); diff --git a/src/main/java/forge/control/input/InputPaySacCost.java b/src/main/java/forge/control/input/InputPaySacCost.java index 3f3c00d157e..06a9661d6e7 100644 --- a/src/main/java/forge/control/input/InputPaySacCost.java +++ b/src/main/java/forge/control/input/InputPaySacCost.java @@ -19,7 +19,6 @@ package forge.control.input; import java.util.List; -import forge.AllZone; import forge.Card; import forge.CardLists; @@ -28,6 +27,7 @@ import forge.Singletons; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.CostSacrifice; import forge.card.spellability.SpellAbility; +import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.gui.match.CMatchUI; @@ -77,7 +77,8 @@ public class InputPaySacCost extends Input { this.ability = sa; this.sacCost = cost; - this.choiceList = CardLists.getValidCards(AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), AllZone.getHumanPlayer(), source); + Player human = Singletons.getControl().getPlayer(); + this.choiceList = CardLists.getValidCards(human.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), human, source); String amountString = cost.getAmount(); this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) : CardFactoryUtil.xCount(source, source.getSVar(amountString)); diff --git a/src/main/java/forge/game/GameLossReason.java b/src/main/java/forge/game/GameLossReason.java index d2f675f0fcd..43a123b1b03 100644 --- a/src/main/java/forge/game/GameLossReason.java +++ b/src/main/java/forge/game/GameLossReason.java @@ -21,10 +21,6 @@ package forge.game; * The Enum GameLossReason. */ public enum GameLossReason { - - /** The Did not lose yet. */ - DidNotLoseYet, // a winner must have this status by the end of the game - /** The Conceded. */ Conceded, // rule 104.3a /** The Life reached zero. */ @@ -36,7 +32,9 @@ public enum GameLossReason { // 104.3e and others /** The Spell effect. */ - SpellEffect + SpellEffect, + + OpponentWon /* * DoorToNothingness, // Door To Nothingness's ability activated diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index c3b6f3c806d..22a06232758 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -19,21 +19,12 @@ import forge.Card; import forge.CardLists; import forge.CardPredicates; import forge.CardUtil; -import forge.Constant.Preferences; import forge.Singletons; -import forge.control.FControl; -import forge.control.input.InputMulligan; +import forge.deck.Deck; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; -import forge.gui.framework.EDocID; -import forge.gui.framework.SDisplayUtil; -import forge.gui.match.CMatchUI; -import forge.gui.match.VMatchUI; -import forge.gui.match.controllers.CMessage; -import forge.gui.match.nonsingleton.VField; import forge.gui.match.views.VAntes; -import forge.gui.toolbox.FLabel; import forge.item.CardPrinted; import forge.properties.ForgePreferences.FPref; import forge.util.Aggregates; @@ -44,6 +35,63 @@ import forge.util.MyRandom; * All of these methods can and should be static. */ public class GameNew { + private static void prepareSingleLibrary(final Player player, final Deck deck, final Map> removedAnteCards, final List rAICards) { + final Random generator = MyRandom.getRandom(); + boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); + final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) + && Singletons.getModel().getMatch().getGameType() == GameType.Constructed; + + + PlayerZone library = player.getZone(ZoneType.Library); + for (final Entry stackOfCards : deck.getMain()) { + final CardPrinted cardPrinted = stackOfCards.getKey(); + for (int i = 0; i < stackOfCards.getValue(); i++) { + + final Card card = cardPrinted.toForgeCard(player); + + // apply random pictures for cards + if ( player.isComputer() ) { + final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount(); + if (cntVariants > 1) { + card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1); + card.setImageFilename(CardUtil.buildFilename(card)); + } + } + + // Assign random foiling on approximately 1:20 cards + if (cardPrinted.isFoil() || (canRandomFoil && MyRandom.percentTrue(5))) { + final int iFoil = MyRandom.getRandom().nextInt(9) + 1; + card.setFoil(iFoil); + } + + if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) { + if(!removedAnteCards.containsKey(player)) + removedAnteCards.put(player, new ArrayList()); + removedAnteCards.get(player).add(card.getName()); + } else { + library.add(card); + } + + // mark card as difficult for AI to play + if ( player.isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) { + rAICards.add(card.getName()); + // get card picture so that it is in the image cache + // ImageCache.getImage(card); + } + } + } + + // Shuffling + // Ai may cheat + if ( player.isComputer() && Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_SMOOTH_LAND) ) { + // do this instead of shuffling Computer's deck + final Iterable c1 = GameNew.smoothComputerManaCurve(player.getCardsIn(ZoneType.Library)); + player.getZone(ZoneType.Library).setCards(c1); + } else + player.shuffle(); + } + + /** * Constructor for new game allowing card lists to be put into play * immediately, and life totals to be adjusted, for computer and human. @@ -51,30 +99,27 @@ public class GameNew { * TODO: Accept something like match state as parameter. Match should be aware of players, * their decks and other special starting conditions. */ - public static void newGame(final PlayerStartsGame... players) { - Singletons.getControl().changeState(FControl.MATCH_SCREEN); - SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); - - // Update observers - AllZone.getStack().updateObservers(); - AllZone.getInputControl().updateObservers(); - AllZone.getGameLog().updateObservers(); - - newGameCleanup(); - newMatchCleanup(); + public static void newGame(final Map playersConditions) { + AllZone.getInputControl().clearInput(); + AllZone.getColorChanger().reset(); - Singletons.getModel().getPreferences().actuateMatchPreferences(); Card.resetUniqueNumber(); - - for( PlayerStartsGame p : players ) { - final Player player = p.getPlayer(); - player.setStartingLife(p.initialLives); + // need this code here, otherwise observables fail + forge.card.trigger.Trigger.resetIDs(); + AllZone.getTriggerHandler().clearTriggerSettings(); + AllZone.getTriggerHandler().clearDelayedTrigger(); + + // friendliness + final Map> removedAnteCards = new HashMap>(); + final List rAICards = new ArrayList(); + + for( Entry p : playersConditions.entrySet() ) { + final Player player = p.getKey(); + player.setStartingLife(p.getValue().getStartingLife()); // what if I call it for AI player? - player.updateObservers(); - player.setDeck(p.getDeck()); PlayerZone bf = player.getZone(ZoneType.Battlefield); - if (p.cardsOnBattlefield != null) { - for (final Card c : p.cardsOnBattlefield) { + if (p.getValue().getCardsOnTable() != null) { + for (final Card c : p.getValue().getCardsOnTable()) { c.addController(player); c.setOwner(player); bf.add(c, false); @@ -83,77 +128,14 @@ public class GameNew { c.refreshUniqueNumber(); } } + + prepareSingleLibrary(player, p.getValue().getDeck(), removedAnteCards, rAICards); + player.updateObservers(); bf.updateObservers(); - p.getPlayer().getZone(ZoneType.Hand).updateObservers(); - } - GameNew.actuateGame(players); - } - - /** - * This must be separated from the newGame method since life totals and - * player details could be adjusted before the game is started. - * - * That process (also cleanup and observer updates) should be done in - * newGame, then when all is ready, call this function. - */ - private static void actuateGame(final PlayerStartsGame... players) { - forge.card.trigger.Trigger.resetIDs(); - AllZone.getTriggerHandler().clearTriggerSettings(); - AllZone.getTriggerHandler().clearDelayedTrigger(); - CMessage.SINGLETON_INSTANCE.updateGameInfo(); - - // friendliness - final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) - && Singletons.getModel().getMatchState().getGameType().equals(GameType.Constructed); - final Random generator = MyRandom.getRandom(); - - - boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); - final Map> removedAnteCards = new HashMap>(); - final List rAICards = new ArrayList(); - - // Create Card libraries out of decks (CardPrinted) - for( PlayerStartsGame p : players ) - { - PlayerZone library = p.getPlayer().getZone(ZoneType.Library); - for (final Entry stackOfCards : p.getDeck().getMain()) { - final CardPrinted cardPrinted = stackOfCards.getKey(); - for (int i = 0; i < stackOfCards.getValue(); i++) { - - final Card card = cardPrinted.toForgeCard(p.getPlayer()); - - // apply random pictures for cards - if ( p.getPlayer().isComputer() ) { - final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount(); - if (cntVariants > 1) { - card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1); - card.setImageFilename(CardUtil.buildFilename(card)); - } - } - - // Assign random foiling on approximately 1:20 cards - if (cardPrinted.isFoil() || (canRandomFoil && MyRandom.percentTrue(5))) { - final int iFoil = MyRandom.getRandom().nextInt(9) + 1; - card.setFoil(iFoil); - } - - if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) { - if(!removedAnteCards.containsKey(p.getPlayer())) - removedAnteCards.put(p.getPlayer(), new ArrayList()); - removedAnteCards.get(p.getPlayer()).add(card.getName()); - } else { - library.add(card); - } - - // mark card as difficult for AI to play - if ( p.getPlayer().isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) { - rAICards.add(card.getName()); - // get card picture so that it is in the image cache - // ImageCache.getImage(card); - } - } - } + player.getZone(ZoneType.Hand).updateObservers(); } + + if (rAICards.size() > 0) { String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards); @@ -167,34 +149,18 @@ public class GameNew { } JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE); } - - // It is supposed that some code to-be-written adds all players passed to this method into game here. - // So, the upcoming code already refers to AllZone.getPlayersInGame() + GameNew.actuateGame(); + } - // Shuffling - final boolean smoothLand = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_SMOOTH_LAND); - for( Player player : Singletons.getModel().getGameState().getPlayers() ) - { - if ( player.isHuman() ) { - for (int i = 0; i < 100; i++) { - player.shuffle(); - } - } - - // Ai may cheat - if ( player.isComputer() ) { - if (smoothLand) { - // do this instead of shuffling Computer's deck - final Iterable c1 = GameNew.smoothComputerManaCurve(player.getCardsIn(ZoneType.Library)); - player.getZone(ZoneType.Library).setCards(c1); - } else { - player.shuffle(); - } - } - - } - + /** + * This must be separated from the newGame method since life totals and + * player details could be adjusted before the game is started. + * + * That process (also cleanup and observer updates) should be done in + * newGame, then when all is ready, call this function. + */ + private static void actuateGame() { // Deciding which cards go to ante if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE)) { @@ -217,15 +183,14 @@ public class GameNew { // Only cut/coin toss if it's the first game of the match - if (Singletons.getModel().getMatchState().getGamesPlayedCount() == 0) { + if (Singletons.getModel().getMatch().getPlayedGames().isEmpty()) { GameNew.seeWhoPlaysFirstDice(); - - } else if (Singletons.getModel().getMatchState().hasWonLastGame(AllZone.getHumanPlayer().getName())) { - // if player won last, AI starts - GameNew.computerPlayOrDraw("Computer lost the last game."); } else { - GameNew.humanPlayOrDraw("Human lost the last game."); + Player human = Singletons.getControl().getPlayer(); + Player goesFirst = Singletons.getModel().getMatch().getLastGameOutcome().isWinner(human.getLobbyPlayer()) ? human.getOpponent() : human; + setPlayersFirstTurn(goesFirst); } + // Draw 7 cards @@ -235,9 +200,6 @@ public class GameNew { p.drawCard(); } } - - CMatchUI.SINGLETON_INSTANCE.setCard(AllZone.getHumanPlayer().getCardsIn(ZoneType.Hand).get(0)); - AllZone.getInputControl().setInput(new InputMulligan()); } // newGame() private static String buildFourColumnList(String firstLine, List cAnteRemoved ) { @@ -254,52 +216,6 @@ public class GameNew { return sb.toString(); } - private static void newGameCleanup() { - final GameState gs = Singletons.getModel().getGameState(); - - gs.setGameSummary(new GameSummary(Iterables.transform(gs.getPlayers(), Player.Accessors.FN_GET_NAME))); - - gs.getPhaseHandler().reset(); - gs.getStack().reset(); - gs.getCombat().reset(); - gs.getEndOfTurn().reset(); - gs.getEndOfCombat().reset(); - gs.getUntap().reset(); - gs.getUpkeep().reset(); - gs.getGameLog().reset(); - gs.setGameOver(false); - - for (final Player p : gs.getPlayers()) { - p.reset(); - for (final ZoneType z : Player.ALL_ZONES) { - p.getZone(z).reset(); - } - } - - gs.getStaticEffects().reset(); - - AllZone.getInputControl().clearInput(); - AllZone.getColorChanger().reset(); - } - - private static void newMatchCleanup() { - if (Singletons.getModel().getMatchState().getGamesPlayedCount() != 0) { return; } - - // TODO restore this functionality!!! - //VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getDocument().setVisible(Preferences.DEV_MODE); - - final List allFields = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); - - for (final VField field : allFields) { - ((FLabel) field.getLblHand()).setHoverable(Preferences.DEV_MODE); - ((FLabel) field.getLblLibrary()).setHoverable(Preferences.DEV_MODE); - } - - VAntes.SINGLETON_INSTANCE.clearAnteCards(); - AllZone.getInputControl().resetInput(); - Singletons.getModel().getMatchState().reset(); - } - // this is where the computer cheats // changes AllZone.getComputerPlayer().getZone(Zone.Library) @@ -371,48 +287,34 @@ public class GameNew { computerDie = MyRandom.getRandom().nextInt(20); } - if (playerDie > computerDie) { - humanPlayOrDraw(dieRollMessage(playerDie, computerDie)); - } - else { - computerPlayOrDraw(dieRollMessage(playerDie, computerDie)); + List allPlayers = Singletons.getModel().getGameState().getPlayers(); + setPlayersFirstTurn(allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size()))); + } + + private static void setPlayersFirstTurn(Player goesFirst) + { + String message = goesFirst + " has won the coin toss."; + if ( goesFirst.isHuman() ) { + if( !humanPlayOrDraw(message) ); + + } else { + computerPlayOrDraw(message); } + Singletons.getModel().getGameState().getPhaseHandler().setPlayerTurn(goesFirst); } // seeWhoPlaysFirstDice() - - private static void computerStartsGame() { - final Player computer = AllZone.getComputerPlayer(); - Singletons.getModel().getGameState().getPhaseHandler().setPlayerTurn(computer); - // AllZone.getGameInfo().setPlayerWhoGotFirstTurn(computer.getName()); - } - - private static String dieRollMessage(int playerDie, int computerDie) { - StringBuilder sb = new StringBuilder(); - sb.append("Human has rolled a: "); - sb.append(playerDie); - sb.append(". "); - sb.append("Computer has rolled a: "); - sb.append(computerDie); - sb.append("."); - return sb.toString(); - } - - private static void humanPlayOrDraw(String message) { + private static boolean humanPlayOrDraw(String message) { final Object[] possibleValues = { "Play", "Draw" }; final Object playDraw = JOptionPane.showOptionDialog(null, message + "\n\nWould you like to play or draw?", "Play or Draw?", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); - if (playDraw.equals(1)) { - computerStartsGame(); - } + return !playDraw.equals(1); } private static void computerPlayOrDraw(String message) { JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "Play or Draw?", JOptionPane.INFORMATION_MESSAGE); - - computerStartsGame(); } } \ No newline at end of file diff --git a/src/main/java/forge/game/GameSummary.java b/src/main/java/forge/game/GameOutcome.java similarity index 57% rename from src/main/java/forge/game/GameSummary.java rename to src/main/java/forge/game/GameOutcome.java index 5250352557b..0d5ae7d90d9 100644 --- a/src/main/java/forge/game/GameSummary.java +++ b/src/main/java/forge/game/GameOutcome.java @@ -1,171 +1,174 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * 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 . - */ -package forge.game; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -/** - *

- * GameInfo class. - *

- * - * @author Forge - * @version $Id$ - */ - -// 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 final class GameSummary { - - /** The player winner. */ - private String playerWinner = "Nobody"; - - /** The player got first turn. */ - // private String playerGotFirstTurn = "Nobody"; - - /** The last turn number. */ - private int lastTurnNumber = 0; - - /** The win condition. */ - private GameEndReason winCondition; - - /** The spell effect win. */ - private String spellEffectWin; - - /** The player rating. */ - private final Map playerRating = new HashMap(); - - /** - * Instantiates a new game summary. - * - * @param names - * the names - */ - public GameSummary(final String... names) { - this(Arrays.asList(names)); - } - - public GameSummary(final Iterable list) { - for (final String n : list) { - this.playerRating.put(n, new GamePlayerRating()); - } - } - - /** - * End. - * - * @param condition - * the condition - * @param winner - * the winner - * @param spellEffect - * the spell effect - */ - public void end(final GameEndReason condition, final String winner, final String spellEffect) { - this.winCondition = condition; - this.playerWinner = winner; - this.spellEffectWin = spellEffect; - } - - /** - * Checks if is draw. - * - * @return true, if is draw - */ - public boolean isDraw() { - return null == this.playerWinner; - } - - /** - * Checks if is winner. - * - * @param name - * the name - * @return true, if is winner - */ - public boolean isWinner(final String name) { - return (name != null) && name.equals(this.playerWinner); - } - - /** - * Gets the winner. - * - * @return the winner - */ - public String getWinner() { - return this.playerWinner; - } - - /** - * Gets the win condition. - * - * @return the win condition - */ - public GameEndReason getWinCondition() { - return this.winCondition; - } - - /** - * Gets the player rating. - * - * @param name - * the name - * @return the player rating - */ - public GamePlayerRating getPlayerRating(final String name) { - return this.playerRating.get(name); - } - - /** - * Gets the turn game ended. - * - * @return the turn game ended - */ - public int getLastTurnNumber() { - return this.lastTurnNumber; - } - - /** - * Sets the player who got first turn. - * - */ - /* - * public void setPlayerWhoGotFirstTurn(final String playerName) { - * this.playerGotFirstTurn = playerName; } - */ - - /** - * Notify next turn. - */ - public void notifyNextTurn() { - this.lastTurnNumber++; - } - - /** - * Gets the win spell effect. - * - * @return the win spell effect - */ - public String getWinSpellEffect() { - return this.spellEffectWin; - } - -} +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * 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 . + */ +package forge.game; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import forge.game.player.LobbyPlayer; +import forge.game.player.Player; +import forge.game.player.PlayerStatistics; + +/** + *

+ * GameInfo class. + *

+ * + * @author Forge + * @version $Id: GameOutcome.java 17559 2012-10-18 07:59:42Z Max mtg $ + */ + +// 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 final class GameOutcome implements Iterable> { + + + /** The player got first turn. */ + // private String playerGotFirstTurn = "Nobody"; + + /** The last turn number. */ + private int lastTurnNumber = 0; + + /** The player rating. */ + private final Map playerRating = new HashMap(4); + + private GameEndReason winCondition; + + /** + * Instantiates a new game summary. + * + * @param names + * the names + */ + public GameOutcome(GameEndReason reason, final Player... names) { + this(reason, Arrays.asList(names)); + } + + public GameOutcome(GameEndReason reason, final Iterable list) { + winCondition = reason; + for (final Player n : list) { + this.playerRating.put(n.getLobbyPlayer(), n.getStats()); + } + } + + + /** + * Checks if is draw. + * + * @return true, if is draw + */ + public boolean isDraw() { + for( PlayerStatistics pv : playerRating.values()) + { + if ( pv.getOutcome().hasWon() ) + return false; + } + return true; + } + + /** + * Checks if is winner. + * + * @param name + * the name + * @return true, if is winner + */ + public boolean isWinner(final LobbyPlayer who) { + PlayerStatistics stats = playerRating.get(who); + return stats.getOutcome().hasWon(); + } + + /** + * Gets the winner. + * + * @return the winner + */ + public LobbyPlayer getWinner() { + for( Entry ps : playerRating.entrySet()) + { + if ( ps.getValue().getOutcome().hasWon() ) + return ps.getKey(); + } + return null; + } + + /** + * Gets the win condition. + * + * @return the win condition + */ + public GameEndReason getWinCondition() { + return this.winCondition; + } + + /** + * Gets the player rating. + * + * @param name + * the name + * @return the player rating + */ + public PlayerStatistics getStatistics(final LobbyPlayer name) { + return this.playerRating.get(name); + } + + /** + * Gets the turn game ended. + * + * @return the turn game ended + */ + public int getLastTurnNumber() { + return this.lastTurnNumber; + } + + /** + * Sets the player who got first turn. + * + */ + /* + * public void setPlayerWhoGotFirstTurn(final String playerName) { + * this.playerGotFirstTurn = playerName; } + */ + + /** + * Gets the win spell effect. + * + * @return the win spell effect + */ + public String getWinSpellEffect() { + for( PlayerStatistics pv : playerRating.values()) + { + if ( pv.getOutcome().hasWon() ) + return pv.getOutcome().altWinSourceName; + } + return null; + } + + /* (non-Javadoc) + * @see java.lang.Iterable#iterator() + */ + @Override + public Iterator> iterator() { + return playerRating.entrySet().iterator(); + } + +} diff --git a/src/main/java/forge/game/GameState.java b/src/main/java/forge/game/GameState.java index c018a9da8f9..97e99458630 100644 --- a/src/main/java/forge/game/GameState.java +++ b/src/main/java/forge/game/GameState.java @@ -32,8 +32,7 @@ import forge.game.phase.EndOfTurn; import forge.game.phase.PhaseHandler; import forge.game.phase.Untap; import forge.game.phase.Upkeep; -import forge.game.player.AIPlayer; -import forge.game.player.HumanPlayer; +import forge.game.player.LobbyPlayer; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.game.zone.MagicStack; @@ -51,14 +50,13 @@ public class GameState { /** The Constant AI_PLAYER_NAME. */ public static final String AI_PLAYER_NAME = "Computer"; - private final List players = new ArrayList(); private final List roPlayers; private final Cleanup cleanup = new Cleanup(); private final EndOfTurn endOfTurn = new EndOfTurn(); private final EndOfCombat endOfCombat = new EndOfCombat(); private final Untap untap = new Untap(); private final Upkeep upkeep = new Upkeep(); - private final PhaseHandler phaseHandler = new PhaseHandler(); + private PhaseHandler phaseHandler = new PhaseHandler(); private final MagicStack stack = new MagicStack(); private final StaticEffects staticEffects = new StaticEffects(); private final TriggerHandler triggerHandler = new TriggerHandler(); @@ -70,15 +68,17 @@ public class GameState { private final PlayerZone stackZone = new PlayerZone(ZoneType.Stack, null); private long timestamp = 0; - private GameSummary gameSummary; - + private int nTurn = 0; + /** * Constructor. + * @param players2 */ - public GameState() { /* no more zones to map here */ - players.add(new HumanPlayer(GameState.HUMAN_PLAYER_NAME)); - players.add(new AIPlayer(GameState.AI_PLAYER_NAME)); - + public GameState(Iterable players2) { /* no more zones to map here */ + List players = new ArrayList(); + for(LobbyPlayer p : players2) { + players.add(p.getIngamePlayer()); + } roPlayers = Collections.unmodifiableList(players); } @@ -238,23 +238,6 @@ public class GameState { this.timestamp = timestamp0; } - /** - * Gets the game info. - * - * @return the game info - */ - public final GameSummary getGameSummary() { - return this.gameSummary; - } - - /** - * Sets the game info. - * - * @param summary0 {@link forge.game.GameSummary} - */ - public final void setGameSummary(final GameSummary summary0) { - this.gameSummary = summary0; - } /** * @return the replacementHandler @@ -273,8 +256,25 @@ public class GameState { /** * @param go the gameOver to set */ - public void setGameOver(boolean go) { - this.gameOver = go; + public void setGameOver() { + this.gameOver = true; + for(Player p : roPlayers) { + p.onGameOver(); + } } + /** + * TODO: Write javadoc for this method. + * @return + */ + public int getTurnNumber() { + return nTurn; + } + + /** + * TODO: Write javadoc for this method. + */ + public void notifyNextTurn() { + nTurn++; + } } diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java new file mode 100644 index 00000000000..eb85a86ddb2 --- /dev/null +++ b/src/main/java/forge/game/MatchController.java @@ -0,0 +1,259 @@ +package forge.game; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import forge.AllZone; +import forge.Singletons; +import forge.Constant.Preferences; +import forge.control.FControl; +import forge.control.input.InputMulligan; +import forge.deck.Deck; +import forge.error.ErrorViewer; +import forge.game.player.ComputerAIGeneral; +import forge.game.player.ComputerAIInput; +import forge.game.player.LobbyPlayer; +import forge.game.player.Player; +import forge.game.player.PlayerType; +import forge.game.zone.ZoneType; +import forge.gui.framework.EDocID; +import forge.gui.framework.SDisplayUtil; +import forge.gui.match.CMatchUI; +import forge.gui.match.VMatchUI; +import forge.gui.match.controllers.CLog; +import forge.gui.match.controllers.CMessage; +import forge.gui.match.controllers.CStack; +import forge.gui.match.nonsingleton.VField; +import forge.gui.match.views.VAntes; +import forge.gui.toolbox.FLabel; +import forge.util.Aggregates; + +/** + * TODO: Write javadoc for this type. + * + */ + +public class MatchController { + + private final Map players = new HashMap(); + private GameType gameType = GameType.Constructed; + + private int gamesPerMatch = 3; + private int gamesToWinMatch = 2; + + private GameState currentGame = null; + + private final List gamesPlayed = new ArrayList(); + private final List gamesPlayedRo; + + public MatchController() { + gamesPlayedRo = Collections.unmodifiableList(gamesPlayed); + } + + /** + * Gets the games played. + * + * @return the games played + */ + public final List getPlayedGames() { + return this.gamesPlayedRo; + } + + /** @return int */ + public int getGamesPerMatch() { + return gamesPerMatch; + } + + /** @return int */ + public int getGamesToWinMatch() { + return gamesToWinMatch; + } + + /** + * TODO: Write javadoc for this method. + * @param reason + * + * @param game + */ + public void addGamePlayed(GameEndReason reason, GameState game) { + if ( !game.isGameOver() ) + throw new RuntimeException("Game is not over yet."); + + GameOutcome result = new GameOutcome(reason, game.getPlayers()); + gamesPlayed.add(result); + } + + /** + * TODO: Write javadoc for this method. + */ + public void startRound() { + + // Will this lose all the ordering? + currentGame = Singletons.getModel().newGame(players.keySet()); + + Map startConditions = new HashMap(); + for (Player p : currentGame.getPlayers()) + startConditions.put(p, players.get(p.getLobbyPlayer())); + + try { + CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getPlayers(), Singletons.getControl().getPlayer()); + Singletons.getModel().getPreferences().actuateMatchPreferences(); + Singletons.getControl().changeState(FControl.MATCH_SCREEN); + SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); + + // set all observers + CMessage.SINGLETON_INSTANCE.subscribe(currentGame); + CLog.SINGLETON_INSTANCE.subscribe(currentGame); + CStack.SINGLETON_INSTANCE.subscribe(currentGame); + + + GameNew.newGame(startConditions); + + Player computerPlayer = Aggregates.firstFieldEquals(currentGame.getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER); + AllZone.getInputControl().setComputer(new ComputerAIInput(new ComputerAIGeneral(computerPlayer))); + + + if (this.getPlayedGames().isEmpty()) { + // TODO restore this functionality!!! + //VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getDocument().setVisible(Preferences.DEV_MODE); + + for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { + ((FLabel) field.getLblHand()).setHoverable(Preferences.DEV_MODE); + ((FLabel) field.getLblLibrary()).setHoverable(Preferences.DEV_MODE); + } + + VAntes.SINGLETON_INSTANCE.clearAnteCards(); + AllZone.getInputControl().resetInput(); + } + + // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch + + CMessage.SINGLETON_INSTANCE.updateGameInfo(this); + // Update observers + AllZone.getStack().updateObservers(); + AllZone.getInputControl().updateObservers(); + AllZone.getGameLog().updateObservers(); + + + for( Player p : currentGame.getPlayers() ) { + p.updateObservers(); + p.getZone(ZoneType.Hand).updateObservers(); + } + + CMatchUI.SINGLETON_INSTANCE.setCard(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Hand).get(0)); + AllZone.getInputControl().setInput(new InputMulligan()); + + } catch (Exception e) { + ErrorViewer.showError(e); + } + // bf.updateObservers(); + // player.updateObservers(); + // player.getZone(ZoneType.Hand).updateObservers(); + + } + + /** + * TODO: Write javadoc for this method. + */ + public void initMatch(GameType type, Map map) { + gamesPlayed.clear(); + players.clear(); + players.putAll(map); + gameType = type; + } + + /** + * TODO: Write javadoc for this method. + */ + public void replayRound() { + gamesPlayed.remove(gamesPlayed.size() - 1); + } + + /** + * TODO: Write javadoc for this method. + * + * @return + */ + public GameType getGameType() { + return gameType; + } + + /** + * TODO: Write javadoc for this method. + * + * @return + */ + public GameOutcome getLastGameOutcome() { + return gamesPlayed.isEmpty() ? null : gamesPlayed.get(gamesPlayed.size() - 1); + } + + public GameState getCurrentGame() { + return currentGame; + } + + /** + * TODO: Write javadoc for this method. + * + * @return + */ + public boolean isMatchOver() { + int[] victories = new int[players.size()]; + for (GameOutcome go : gamesPlayed) { + LobbyPlayer winner = go.getWinner(); + int i = 0; + for (LobbyPlayer p : players.keySet()) { + if (p.equals(winner)) { + victories[i]++; + break; // can't have 2 winners per game + } + i++; + } + } + + for (int score : victories) { + if (score >= gamesToWinMatch) + return true; + } + return gamesPlayed.size() >= gamesPerMatch; + } + + /** + * TODO: Write javadoc for this method. + * + * @param questPlayer + * @return + */ + public int getGamesWonBy(LobbyPlayer questPlayer) { + int sum = 0; + for (GameOutcome go : gamesPlayed) { + if (go.getWinner().equals(questPlayer)) { + sum++; + } + } + return sum; + } + + /** + * TODO: Write javadoc for this method. + * + * @param questPlayer + * @return + */ + public boolean isWonBy(LobbyPlayer questPlayer) { + return getGamesWonBy(questPlayer) >= gamesToWinMatch; + } + + /** + * TODO: Write javadoc for this method. + * + * @param lobbyPlayer + * @return + */ + public Deck getPlayersDeck(LobbyPlayer lobbyPlayer) { + PlayerStartConditions cond = players.get(lobbyPlayer); + return cond == null ? null : cond.getDeck(); + } +} diff --git a/src/main/java/forge/game/MatchStartHelper.java b/src/main/java/forge/game/MatchStartHelper.java new file mode 100644 index 00000000000..f9012900514 --- /dev/null +++ b/src/main/java/forge/game/MatchStartHelper.java @@ -0,0 +1,30 @@ +package forge.game; + +import java.util.HashMap; +import java.util.Map; + +import forge.deck.Deck; +import forge.game.player.LobbyPlayer; + +/** + * TODO: Write javadoc for this type. + * + */ +public class MatchStartHelper { + private final Map players = new HashMap(); + + public void addPlayer(LobbyPlayer player, PlayerStartConditions c) { + players.put(player,c); + } + + public void addPlayer(LobbyPlayer player, Deck deck) { + players.put(player, new PlayerStartConditions(deck)); + } + + public Map getPlayerMap() + { + return players; + } + + +} diff --git a/src/main/java/forge/game/PlayerStartConditions.java b/src/main/java/forge/game/PlayerStartConditions.java new file mode 100644 index 00000000000..01172c1ddf0 --- /dev/null +++ b/src/main/java/forge/game/PlayerStartConditions.java @@ -0,0 +1,36 @@ +package forge.game; + +import java.util.List; + +import forge.Card; +import forge.deck.Deck; + + +public class PlayerStartConditions { + private final Deck deck; + private int startingLife = 20; + private List cardsOnTable = null; + + public PlayerStartConditions( Deck deck0 ) { + deck = deck0; + } + + public final Deck getDeck() { + return deck; + } + public final int getStartingLife() { + return startingLife; + } + public final List getCardsOnTable() { + return cardsOnTable; + } + + public final void setStartingLife(int startingLife) { + this.startingLife = startingLife; + } + public final void setCardsOnTable(List cardsOnTable) { + this.cardsOnTable = cardsOnTable; + } + + +} diff --git a/src/main/java/forge/game/PlayerStartsGame.java b/src/main/java/forge/game/PlayerStartsGame.java deleted file mode 100644 index bcba0376979..00000000000 --- a/src/main/java/forge/game/PlayerStartsGame.java +++ /dev/null @@ -1,35 +0,0 @@ -package forge.game; - -import java.util.List; - -import forge.Card; -import forge.deck.Deck; -import forge.game.player.Player; - -/** - * TODO: Write javadoc for this type. - * @param - * - */ -public class PlayerStartsGame { - - private final Player player; - private final Deck deck; - public int initialLives = 20; - public List cardsOnBattlefield = null; - - public PlayerStartsGame(Player who, Deck cards) { - player = who; - deck = cards; - } - - public Player getPlayer() { - return player; - } - - public Deck getDeck() { - return deck; - } - - -} diff --git a/src/main/java/forge/game/limited/GauntletMini.java b/src/main/java/forge/game/limited/GauntletMini.java index 5870c23af95..3f6053d23b0 100644 --- a/src/main/java/forge/game/limited/GauntletMini.java +++ b/src/main/java/forge/game/limited/GauntletMini.java @@ -19,16 +19,17 @@ package forge.game.limited; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; + import java.util.List; -import forge.AllZone; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; +import forge.game.player.PlayerType; import forge.gui.SOverlayUtils; -import forge.gui.match.CMatchUI; /** *

@@ -158,10 +159,15 @@ public class GauntletMini { @Override public Object doInBackground() { - CMatchUI.SINGLETON_INSTANCE.initMatch(null); - Singletons.getModel().getMatchState().setGameType(gauntletType); - GameNew.newGame( new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDecks.get(currentRound))); + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDecks.get(currentRound)); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(gauntletType, starter.getPlayerMap()); + mc.startRound(); return null; } diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index 1e0faa6cfae..870fb27f7cb 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -382,7 +382,7 @@ public class CombatUtil { */ public static boolean finishedMandatoryBlocks(final Combat combat) { - final List blockers = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + final List blockers = AllZoneUtil.getCreaturesInPlay(Singletons.getControl().getPlayer()); final List attackers = combat.getAttackerList(); // if a creature does not block but should, return false diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index e3695264fb4..359af529f88 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -19,7 +19,6 @@ package forge.game.phase; import java.util.HashMap; import java.util.List; -import java.util.Observer; import java.util.Stack; import com.esotericsoftware.minlog.Log; @@ -53,27 +52,39 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { /** Constant serialVersionUID=5207222278370963197L. */ private static final long serialVersionUID = 5207222278370963197L; - private int phaseIndex; - private int turn; - - // Please use getX, setX, and incrementX methods instead of directly - // accessing the following: - /** Constant GameBegins=0. */ - private static int gameBegins = 0; + private int phaseIndex = 0; + private int turn = 1; private final Stack extraTurns = new Stack(); - private int extraCombats; + private int extraCombats = 0; - private int nCombatsThisTurn; - private boolean bPreventCombatDamageThisTurn; + private int nCombatsThisTurn = 0; + private boolean bPreventCombatDamageThisTurn = false; - private Player playerTurn = AllZone.getHumanPlayer(); + private Player playerTurn = null; - private Player skipToTurn = AllZone.getHumanPlayer(); + private Player skipToTurn = null; private PhaseType skipToPhase = PhaseType.CLEANUP; private boolean autoPass = false; + // priority player + + private Player pPlayerPriority = null; + private Player pFirstPriority = null; + private boolean bPhaseEffects = true; + private boolean bSkipPhase = true; + private boolean bCombat = false; + private boolean bRepeat = false; + + /** The need to next phase. */ + private boolean needToNextPhase = false; + + // This should only be true four times! that is for the initial nextPhases + // in MyObservable + /** The need to next phase init. */ + private int needToNextPhaseInit = 0; + /** *

* isPlayerTurn. @@ -112,8 +123,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { // priority player - private Player pPlayerPriority = AllZone.getHumanPlayer(); - /** *

* getPriorityPlayer. @@ -137,8 +146,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.pPlayerPriority = p; } - private Player pFirstPriority = AllZone.getHumanPlayer(); - /** *

* getFirstPriority. @@ -188,8 +195,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.setPriority(this.playerTurn); } - private boolean bPhaseEffects = true; - /** *

* doPhaseEffects. @@ -213,8 +218,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.bPhaseEffects = b; } - private boolean bSkipPhase = true; - /** *

* doSkipPhase. @@ -238,8 +241,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.bSkipPhase = b; } - private boolean bCombat = false; - /** *

* inCombat. @@ -263,8 +264,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.bCombat = b; } - private boolean bRepeat = false; - /** *

* repeatPhase. @@ -274,38 +273,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.bRepeat = true; } - /** - *

- * Constructor for PhaseHandler. - *

- */ - public PhaseHandler() { - this.reset(); - } - - /** - *

- * reset. - *

- */ - public final void reset() { - this.turn = 1; - this.playerTurn = AllZone.getHumanPlayer(); - this.resetPriority(); - this.bPhaseEffects = true; - this.needToNextPhase = false; - PhaseHandler.setGameBegins(0); - this.phaseIndex = 0; - this.extraTurns.clear(); - this.nCombatsThisTurn = 0; - this.extraCombats = 0; - this.bPreventCombatDamageThisTurn = false; - this.bCombat = false; - this.bRepeat = false; - this.autoPass = false; - this.updateObservers(); - } - /** *

* handleBeginPhase. @@ -902,15 +869,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { } } - /** {@inheritDoc} */ - @Override - public final void addObserver(final Observer o) { - super.addObserver(o); - } - - /** The need to next phase. */ - private boolean needToNextPhase = false; - /** *

* Setter for the field needToNextPhase. @@ -934,11 +892,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { return this.needToNextPhase; } - // This should only be true four times! that is for the initial nextPhases - // in MyObservable - /** The need to next phase init. */ - private int needToNextPhaseInit = 0; - /** *

* isNeedToNextPhaseInit. @@ -998,31 +951,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { return now.isPlayerTurn(player) && now.getPhase().isMain() && onlyThis; } - - - /** - *

- * setGameBegins. - *

- * - * @param gameBegins - * a int. - */ - public static void setGameBegins(final int gameBegins) { - PhaseHandler.gameBegins = gameBegins; - } - - /** - *

- * getGameBegins. - *

- * - * @return a int. - */ - public static int getGameBegins() { - return PhaseHandler.gameBegins; - } - // this is a hack for the setup game state mode, do not use outside of // devSetupGameState code // as it avoids calling any of the phase effects that may be necessary in a diff --git a/src/main/java/forge/game/phase/PhaseUtil.java b/src/main/java/forge/game/phase/PhaseUtil.java index eff33e64888..f0f368567a1 100644 --- a/src/main/java/forge/game/phase/PhaseUtil.java +++ b/src/main/java/forge/game/phase/PhaseUtil.java @@ -87,8 +87,8 @@ public class PhaseUtil { final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler(); final Player turn = ph.getPlayerTurn(); - Singletons.getModel().getGameSummary().notifyNextTurn(); - CMessage.SINGLETON_INSTANCE.updateGameInfo(); + Singletons.getModel().getGameState().notifyNextTurn(); + CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch()); AllZone.getCombat().reset(); AllZone.getCombat().setAttackingPlayer(turn); diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index e7aa5591797..c6386904f2a 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -50,24 +50,8 @@ public class AIPlayer extends Player { * @param myName * a {@link java.lang.String} object. */ - public AIPlayer(final String myName) { - this(myName, 20, 0); - } - - /** - *

- * Constructor for AIPlayer. - *

- * - * @param myName - * a {@link java.lang.String} object. - * @param myLife - * a int. - * @param myPoisonCounters - * a int. - */ - public AIPlayer(final String myName, final int myLife, final int myPoisonCounters) { - super(myName, myLife, myPoisonCounters); + public AIPlayer(final LobbyPlayer player) { + super(player); } diff --git a/src/main/java/forge/game/player/HumanPlayer.java b/src/main/java/forge/game/player/HumanPlayer.java index f549ccfebd6..94e594e914a 100644 --- a/src/main/java/forge/game/player/HumanPlayer.java +++ b/src/main/java/forge/game/player/HumanPlayer.java @@ -29,6 +29,8 @@ import forge.control.input.Input; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.match.CMatchUI; +import forge.quest.QuestController; +import forge.quest.bazaar.QuestItemType; /** *

@@ -48,24 +50,8 @@ public class HumanPlayer extends Player { * @param myName * a {@link java.lang.String} object. */ - public HumanPlayer(final String myName) { - this(myName, 20, 0); - } - - /** - *

- * Constructor for HumanPlayer. - *

- * - * @param myName - * a {@link java.lang.String} object. - * @param myLife - * a int. - * @param myPoisonCounters - * a int. - */ - public HumanPlayer(final String myName, final int myLife, final int myPoisonCounters) { - super(myName, myLife, myPoisonCounters); + public HumanPlayer(final LobbyPlayer player) { + super(player); } // ////////////// @@ -222,4 +208,15 @@ public class HumanPlayer extends Player { return PlayerType.HUMAN; } + @Override + public final int doMulligan() { + int newHand = super.doMulligan(); + final QuestController quest = Singletons.getModel().getQuest(); + if (quest.isLoaded() && quest.getAssets().hasItem(QuestItemType.SLEIGHT) && (getStats().getMulliganCount() == 1)) { + drawCard(); + newHand++; + getStats().notifyOpeningHandSize(newHand); + } + return newHand; + } } // end HumanPlayer class diff --git a/src/main/java/forge/game/player/LobbyPlayer.java b/src/main/java/forge/game/player/LobbyPlayer.java new file mode 100644 index 00000000000..76997664192 --- /dev/null +++ b/src/main/java/forge/game/player/LobbyPlayer.java @@ -0,0 +1,75 @@ +package forge.game.player; + +/** + * This means a player's part unchanged for all games. + * + * May store player's assets here. + * + */ +public class LobbyPlayer { + + final protected PlayerType type; + final protected String name; + protected String picture; + + public LobbyPlayer(PlayerType type, String name) + { + this.type = type; + this.name = name; + } + + public final String getPicture() { + return picture; + } + + public final void setPicture(String picture) { + this.picture = picture; + } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public Player getIngamePlayer() { + if ( type == PlayerType.HUMAN ) + return new HumanPlayer(this); + else + return new AIPlayer(this); + } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LobbyPlayer other = (LobbyPlayer) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (type != other.type) + return false; + return true; + } +} diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index d0b7c3eab85..b9b615b3176 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -51,7 +51,6 @@ import forge.card.replacement.ReplacementResult; import forge.card.spellability.SpellAbility; import forge.card.staticability.StaticAbility; import forge.card.trigger.TriggerType; -import forge.deck.Deck; import forge.game.GameLossReason; import forge.game.phase.PhaseHandler; import forge.game.zone.PlayerZone; @@ -69,15 +68,15 @@ import forge.util.MyRandom; * @author Forge * @version $Id$ */ -public abstract class Player extends GameEntity implements Comparable { +public abstract class Player extends GameEntity implements Comparable { /** The poison counters. */ - private int poisonCounters; + private int poisonCounters = 0; /** The life. */ - private int life; + private int life = 20; /** The life this player started the game with. */ - private int startingLife; + private int startingLife = 20; /** The assigned damage. */ private final Map assignedDamage = new HashMap(); @@ -88,24 +87,6 @@ public abstract class Player extends GameEntity implements Comparable { /** The num power surge lands. */ private int numPowerSurgeLands; - /** The alt win. */ - private boolean altWin = false; - - /** The alt win source name. */ - private String altWinSourceName; - - /** The alt lose. */ - // private boolean altLose = false; - - /** The loss state. */ - private GameLossReason lossState = GameLossReason.DidNotLoseYet; - - /** The lose condition spell. */ - private String loseConditionSpell; - - /** The n turns. */ - private int nTurns = 0; - /** The skip next untap. */ private boolean skipNextUntap = false; @@ -122,7 +103,7 @@ public abstract class Player extends GameEntity implements Comparable { private int maxHandSize = 7; /** The last drawn card. */ - private Card lastDrawnCard; + private Card lastDrawnCard = null; /** The num drawn this turn. */ private int numDrawnThisTurn = 0; @@ -134,7 +115,7 @@ public abstract class Player extends GameEntity implements Comparable { private ArrayList keywords = new ArrayList(); /** The mana pool. */ - private ManaPool manaPool = null; + private ManaPool manaPool = new ManaPool(this); /** The must attack entity. */ private Object mustAttackEntity = null; @@ -148,24 +129,19 @@ public abstract class Player extends GameEntity implements Comparable { /** The zones. */ private final Map zones = new EnumMap(ZoneType.class); + private PlayerStatistics stats = new PlayerStatistics(); + /** The Constant ALL_ZONES. */ public static final List ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield, - ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante, ZoneType.Stack)); + ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante)); - // Moved deck here from Constants.Runtime - private Deck deck; - /** - *

- * Constructor for Player. - *

- * - * @param myName - * a {@link java.lang.String} object. - */ - public Player(final String myName) { - this(myName, 20, 0); + + private LobbyPlayer lobbyPlayer; + + public final PlayerOutcome getOutcome() { + return stats.getOutcome(); } /** @@ -180,48 +156,19 @@ public abstract class Player extends GameEntity implements Comparable { * @param myPoisonCounters * a int. */ - public Player(final String myName, final int myLife, final int myPoisonCounters) { + public Player(LobbyPlayer lobbyPlayer0) { + lobbyPlayer = lobbyPlayer0; for (final ZoneType z : Player.ALL_ZONES) { - final PlayerZone toPut = z == ZoneType.Battlefield ? new PlayerZoneBattlefield(z, this) + final PlayerZone toPut = z == ZoneType.Battlefield + ? new PlayerZoneBattlefield(z, this) : new PlayerZone(z, this); this.zones.put(z, toPut); } - - this.reset(); - - this.setName(myName); - this.life = myLife; - this.poisonCounters = myPoisonCounters; + this.setName(lobbyPlayer.getName()); } - /** - *

- * reset. - *

- */ - public final void reset() { - this.life = 20; - this.lifeLostThisTurn = 0; - this.poisonCounters = 0; - this.assignedDamage.clear(); - this.setPreventNextDamage(0); - this.lastDrawnCard = null; - this.numDrawnThisTurn = 0; - this.slowtripList = new ArrayList(); - this.nTurns = 0; - this.altWin = false; - this.altWinSourceName = null; - // altLose = false; - this.lossState = GameLossReason.DidNotLoseYet; - this.loseConditionSpell = null; - this.maxLandsToPlay = 1; - this.numLandsPlayed = 0; - this.prowl = new ArrayList(); - - this.keywords.clear(); - this.manaPool = new ManaPool(this); - - this.updateObservers(); + public final PlayerStatistics getStats() { + return stats; } /** @@ -1266,6 +1213,32 @@ public abstract class Player extends GameEntity implements Comparable { } return drawn; } + + /** + * + * TODO Write javadoc for this method. + * + * @param player + * a Player object + * @param playerRating + * a GamePlayerRating object + * @return an int + */ + public int doMulligan() { + final List hand = getCardsIn(ZoneType.Hand); + for (final Card c : hand) { + Singletons.getModel().getGameAction().moveToLibrary(c); + } + shuffle(); + final int newHand = hand.size() - 1; + for (int i = 0; i < newHand; i++) { + drawCard(); + } + AllZone.getGameLog().add("Mulligan", this + " has mulliganed down to " + newHand + " cards.", 0); + stats.notifyHasMulliganed(); + stats.notifyOpeningHandSize(newHand); + return newHand; + } /** *

@@ -1307,7 +1280,7 @@ public abstract class Player extends GameEntity implements Comparable { } } - if (PhaseHandler.getGameBegins() == 1) { + if (Singletons.getModel().getGameState() != null) { this.setLastDrawnCard(c); c.setDrawnThisTurn(true); this.numDrawnThisTurn++; @@ -1441,7 +1414,9 @@ public abstract class Player extends GameEntity implements Comparable { * @return the all cards */ public final List getAllCards() { - return this.getCardsIn(Player.ALL_ZONES); + List allExcStack = this.getCardsIn(Player.ALL_ZONES); + allExcStack.addAll(getCardsIn(ZoneType.Stack)); + return allExcStack; } /** @@ -2035,7 +2010,7 @@ public abstract class Player extends GameEntity implements Comparable { * @return a int. */ public final int getTurn() { - return this.nTurns; + return this.stats.getTurnsPlayed(); } /** @@ -2044,7 +2019,7 @@ public abstract class Player extends GameEntity implements Comparable { *

*/ public final void incrementTurn() { - this.nTurns++; + this.stats.nextTurn(); } /** @@ -2116,48 +2091,6 @@ public abstract class Player extends GameEntity implements Comparable { // Game win/loss - /** - *

- * Getter for the field altWin. - *

- * - * @return a boolean. - */ - public final boolean getAltWin() { - return this.altWin; - } - - /** - *

- * Getter for the field winCondition. - *

- * - * @return a {@link java.lang.String} object. - */ - public final String getWinConditionSource() { - return this.altWinSourceName; - } - - /** - *

- * Getter for the field loseCondition. - *

- * - * @return a {@link java.lang.String} object. - */ - public final GameLossReason getLossState() { - return this.lossState; - } - - /** - * Gets the loss condition source. - * - * @return the loss condition source - */ - public final String getLossConditionSource() { - return this.loseConditionSpell; - } - /** *

* altWinConditionMet. @@ -2171,8 +2104,8 @@ public abstract class Player extends GameEntity implements Comparable { System.out.println("Tried to win, but currently can't."); return; } - this.altWin = true; - this.altWinSourceName = sourceName; + this.setOutcome(PlayerOutcome.altWin(sourceName)); + } /** @@ -2187,22 +2120,23 @@ public abstract class Player extends GameEntity implements Comparable { * @return a boolean. */ public final boolean loseConditionMet(final GameLossReason state, final String spellName) { - if (this.cantLose()) { - System.out.println("Tried to lose, but currently can't."); - return false; + if ( state != GameLossReason.OpponentWon ) { + if (this.cantLose()) { + System.out.println("Tried to lose, but currently can't."); + return false; + } + + // Replacement effects + final HashMap runParams = new HashMap(); + runParams.put("Affected", this); + runParams.put("Event", "GameLoss"); + + if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) { + return false; + } } - // Replacement effects - final HashMap runParams = new HashMap(); - runParams.put("Affected", this); - runParams.put("Event", "GameLoss"); - - if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) { - return false; - } - - this.lossState = state; - this.loseConditionSpell = spellName; + setOutcome(PlayerOutcome.loss(state, spellName)); return true; } @@ -2210,8 +2144,7 @@ public abstract class Player extends GameEntity implements Comparable { * Concede. */ public final void concede() { // No cantLose checks - just lose - this.lossState = GameLossReason.Conceded; - this.loseConditionSpell = null; + setOutcome(PlayerOutcome.concede()); } /** @@ -2222,7 +2155,7 @@ public abstract class Player extends GameEntity implements Comparable { * @return a boolean. */ public final boolean cantLose() { - if (this.lossState == GameLossReason.Conceded) { + if (this.getOutcome() != null && this.getOutcome().lossState == GameLossReason.Conceded) { return false; } @@ -2258,11 +2191,10 @@ public abstract class Player extends GameEntity implements Comparable { * * @return a boolean. */ - public final boolean hasLost() { - - if (this.lossState != GameLossReason.DidNotLoseYet) { - return this.loseConditionMet(this.lossState, null); - } + public final boolean checkLoseCondition() { + + if ( this.getOutcome() != null ) + return this.getOutcome().lossState != null; if (this.poisonCounters >= 10) { return this.loseConditionMet(GameLossReason.Poisoned, null); @@ -2287,8 +2219,10 @@ public abstract class Player extends GameEntity implements Comparable { if (this.cantWin()) { return false; } + // in multiplayer game one player's win is replaced by all other's lose (rule 103.4h) + // so if someone cannot lose, the game appears to continue - return this.altWin; + return this.getOutcome() != null && this.getOutcome().lossState == null; } /** @@ -2714,16 +2648,15 @@ public abstract class Player extends GameEntity implements Comparable { return (41 * (41 + this.getName().hashCode())); } - public Deck getDeck() { - return deck; - } - - public void setDeck(Deck deck) { - this.deck = deck; - } - public static class Predicates { + public static final Predicate NOT_LOST = new Predicate() { + @Override + public boolean apply(Player p) { + return p.getOutcome() == null || p.getOutcome().hasWon(); + } + }; + public static Predicate isType(final PlayerType type) { return new Predicate() { @Override @@ -2735,6 +2668,13 @@ public abstract class Player extends GameEntity implements Comparable { } public static class Accessors { + public static Function FN_GET_LOBBY_PLAYER = new Function(){ + @Override + public LobbyPlayer apply(Player input) { + return input.getLobbyPlayer(); + } + }; + public static Function FN_GET_LIFE = new Function(){ @Override public Integer apply(Player input) { @@ -2765,4 +2705,24 @@ public abstract class Player extends GameEntity implements Comparable { }; } } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public LobbyPlayer getLobbyPlayer() { + return lobbyPlayer; + } + + private void setOutcome(PlayerOutcome outcome) { + stats.setOutcome(outcome); + } + + /** + * TODO: Write javadoc for this method. + */ + public void onGameOver() { + if ( null == stats.getOutcome() ) // not lost? + setOutcome(PlayerOutcome.win()); // then won! + } } diff --git a/src/main/java/forge/game/player/PlayerOutcome.java b/src/main/java/forge/game/player/PlayerOutcome.java new file mode 100644 index 00000000000..8de14a65bb8 --- /dev/null +++ b/src/main/java/forge/game/player/PlayerOutcome.java @@ -0,0 +1,57 @@ +package forge.game.player; + +import forge.game.GameLossReason; + +/** + * TODO: Write javadoc for this type. + */ +public class PlayerOutcome { + /** The alt win source name. */ + public final String altWinSourceName; + /** The loss state. */ + public final GameLossReason lossState; + /** The lose condition spell. */ + public final String loseConditionSpell; + + private PlayerOutcome(String altWinSourceName, GameLossReason lossState, String loseConditionSpell) { + this.altWinSourceName= altWinSourceName; + this.loseConditionSpell = loseConditionSpell; + this.lossState = lossState; + } + + /** + * TODO: Write javadoc for this method. + * @param sourceName + * @return + */ + public static PlayerOutcome win() { + return new PlayerOutcome(null, null, null); + } + + public static PlayerOutcome altWin(String sourceName) { + return new PlayerOutcome(sourceName, null, null); + } + + /** + * TODO: Write javadoc for this method. + * @param state + * @param spellName + * @return + */ + public static PlayerOutcome loss(GameLossReason state, String spellName) { + return new PlayerOutcome(null, state, spellName); + } + + /** + * TODO: Write javadoc for this method. + * @return + */ + public static PlayerOutcome concede() { + return new PlayerOutcome(null, GameLossReason.Conceded, null); + } + + public boolean hasWon() { + return lossState == null; + } + +} \ No newline at end of file diff --git a/src/main/java/forge/game/GamePlayerRating.java b/src/main/java/forge/game/player/PlayerStatistics.java similarity index 62% rename from src/main/java/forge/game/GamePlayerRating.java rename to src/main/java/forge/game/player/PlayerStatistics.java index aeab8a05a1a..d36ba41a219 100644 --- a/src/main/java/forge/game/GamePlayerRating.java +++ b/src/main/java/forge/game/player/PlayerStatistics.java @@ -15,14 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.game; +package forge.game.player; /** * The Class GamePlayerRating. * * @author Max */ -public class GamePlayerRating { +public class PlayerStatistics { /** The opening hand size. */ private int openingHandSize = 7; @@ -30,42 +30,10 @@ public class GamePlayerRating { /** The times mulliganed. */ private int timesMulliganed = 0; - /** The loss reason. */ - private GameLossReason lossReason = GameLossReason.DidNotLoseYet; + private int turnsPlayed = 0; - /** The loss spell name. */ - private String lossSpellName; - - /** - * Gets the loss reason. - * - * @return the loss reason - */ - public final GameLossReason getLossReason() { - return this.lossReason; - } - - /** - * Sets the loss reason. - * - * @param loseCondition - * the lose condition - * @param spellName - * the spell name - */ - public void setLossReason(final GameLossReason loseCondition, final String spellName) { - this.lossReason = loseCondition; - this.lossSpellName = spellName; - } - - /** - * Gets the loss spell name. - * - * @return the loss spell name - */ - public String getLossSpellName() { - return this.lossSpellName; - } + + private PlayerOutcome outcome; /** * Gets the opening hand size. @@ -102,4 +70,20 @@ public class GamePlayerRating { this.openingHandSize = newHand; } + public int getTurnsPlayed() { + return turnsPlayed; + } + + public void nextTurn() { + this.turnsPlayed++; + } + + public PlayerOutcome getOutcome() { + return outcome; + } + + public void setOutcome(PlayerOutcome gameOutcome) { + this.outcome = gameOutcome; + } + } diff --git a/src/main/java/forge/game/zone/PlayerZone.java b/src/main/java/forge/game/zone/PlayerZone.java index 4229a4cbb78..063ddc770cb 100644 --- a/src/main/java/forge/game/zone/PlayerZone.java +++ b/src/main/java/forge/game/zone/PlayerZone.java @@ -46,7 +46,7 @@ public class PlayerZone extends MyObservable implements IPlayerZone, Observer, j private static final long serialVersionUID = -5687652485777639176L; /** The cards. */ - protected final List cardList; + protected final List cardList = new ArrayList(); protected final Collection roCardList; private final ZoneType zoneName; private final Player player; @@ -70,7 +70,6 @@ public class PlayerZone extends MyObservable implements IPlayerZone, Observer, j public PlayerZone(final ZoneType zone, final Player inPlayer) { this.zoneName = zone; this.player = inPlayer; - this.cardList = new ArrayList(); this.roCardList = Collections.unmodifiableCollection(cardList); } diff --git a/src/main/java/forge/game/zone/ZoneType.java b/src/main/java/forge/game/zone/ZoneType.java index 65b8bd1465f..8f944203af7 100644 --- a/src/main/java/forge/game/zone/ZoneType.java +++ b/src/main/java/forge/game/zone/ZoneType.java @@ -1,6 +1,7 @@ package forge.game.zone; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -33,7 +34,7 @@ public enum ZoneType { /** Ante. */ Ante(false); - public static final ZoneType[] STATIC_ABILITIES_SOURCE_ZONES = new ZoneType[]{Battlefield, Graveyard, Exile/*, Hand*/}; + public static final List STATIC_ABILITIES_SOURCE_ZONES = Arrays.asList(new ZoneType[]{Battlefield, Graveyard, Exile/*, Hand*/}); private final boolean holdsHiddenInfo; private ZoneType(boolean holdsHidden) { diff --git a/src/main/java/forge/gui/GuiInput.java b/src/main/java/forge/gui/GuiInput.java index 178da6f6b7c..3a629c936eb 100644 --- a/src/main/java/forge/gui/GuiInput.java +++ b/src/main/java/forge/gui/GuiInput.java @@ -22,8 +22,8 @@ import java.util.Observer; import forge.AllZone; import forge.Card; -import forge.Singletons; import forge.control.input.Input; +import forge.game.GameState; import forge.game.player.Player; import forge.game.zone.PlayerZone; import forge.util.MyObservable; @@ -41,16 +41,6 @@ public class GuiInput extends MyObservable implements Observer { /** The input. */ private Input input; - /** - *

- * Constructor for GuiInput. - *

- */ - public GuiInput() { - AllZone.getInputControl().addObserver(this); - AllZone.getStack().addObserver(this); - Singletons.getModel().getGameState().getPhaseHandler().addObserver(this); - } /** {@inheritDoc} */ @Override @@ -137,4 +127,13 @@ public class GuiInput extends MyObservable implements Observer { public Input getInput() { return this.input; } + + /** + * TODO: Write javadoc for this method. + */ + public void subscribe(GameState game) { + AllZone.getInputControl().addObserver(this); + game.getStack().addObserver(this); + game.getPhaseHandler().addObserver(this); + } } diff --git a/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java index c8a9c886374..38a67f7a505 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java @@ -46,6 +46,8 @@ public enum CAllDecks implements ICDoc { public void execute() { importDeck(); } }); } + + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#update() */ diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java index d84568ef4eb..48514a33b41 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java @@ -245,4 +245,5 @@ public enum CCurrentDeck implements ICDoc { } return null; } + } diff --git a/src/main/java/forge/gui/framework/ICDoc.java b/src/main/java/forge/gui/framework/ICDoc.java index 162f1b4b932..86dee3705c8 100644 --- a/src/main/java/forge/gui/framework/ICDoc.java +++ b/src/main/java/forge/gui/framework/ICDoc.java @@ -32,4 +32,5 @@ public interface ICDoc { * Update whatever content is in the panel. */ void update(); + } diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java index 4b0f9b66d19..cb7a8853318 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java @@ -16,16 +16,16 @@ import javax.swing.SwingWorker; import org.apache.commons.lang3.ArrayUtils; -import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil.DeckTypes; import forge.deck.generate.GenerateThemeDeck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; import forge.game.player.PlayerType; import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; @@ -250,15 +250,16 @@ public enum CSubmenuGauntletContests implements ICDoc { @Override public Object doInBackground() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - - Deck human = gd.getUserDeck(); Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); - - if (human != null && aiDeck != null) { - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); - } + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), gd.getUserDeck()); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + mc.startRound(); return null; } diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java index 36746a72150..6263ce5cf2d 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java @@ -9,13 +9,14 @@ import java.util.List; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; +import forge.game.player.PlayerType; import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; import forge.gui.SOverlayUtils; @@ -103,16 +104,16 @@ public enum CSubmenuGauntletLoad implements ICDoc { @Override public Object doInBackground() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - - Deck human = gd.getUserDeck(); - Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); - - if (human != null && aiDeck != null) { - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); - } + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), gd.getUserDeck()); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + mc.startRound(); return null; } diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java index 0eb94afe291..df7186858d1 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletQuick.java @@ -16,16 +16,16 @@ import javax.swing.SwingWorker; import org.apache.commons.lang3.ArrayUtils; -import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil.DeckTypes; import forge.deck.generate.GenerateThemeDeck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; import forge.game.player.PlayerType; import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; @@ -293,15 +293,16 @@ public enum CSubmenuGauntletQuick implements ICDoc { @Override public Object doInBackground() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - - Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); - - Deck human = gd.getUserDeck(); - Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - if (human != null && aiDeck != null) { - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); - } + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), gd.getUserDeck()); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Gauntlet, starter.getPlayerMap()); + mc.startRound(); return null; } diff --git a/src/main/java/forge/gui/home/multiplayer/CSubmenuMultiTest.java b/src/main/java/forge/gui/home/multiplayer/CSubmenuMultiTest.java index 905b339f0bd..20ec798ceb0 100644 --- a/src/main/java/forge/gui/home/multiplayer/CSubmenuMultiTest.java +++ b/src/main/java/forge/gui/home/multiplayer/CSubmenuMultiTest.java @@ -2,23 +2,21 @@ package forge.gui.home.multiplayer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; - import javax.swing.JRadioButton; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckgenUtil; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; import forge.game.player.PlayerType; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.gui.match.CMatchUI; /** * Controls the deck editor submenu option in the home UI. @@ -92,13 +90,16 @@ public enum CSubmenuMultiTest implements ICDoc { Deck humanDeck = DeckgenUtil.getRandomColorDeck(PlayerType.HUMAN); Deck aiDeck = DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER); - CMatchUI.SINGLETON_INSTANCE.initMatch(numFields, numHands); - Singletons.getModel().getMatchState().setGameType(GameType.Constructed); - - if (humanDeck != null && aiDeck != null) { - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); - } + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck); + for( int i = 1; i < numFields; i++ ) + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Constructed, starter.getPlayerMap()); + mc.startRound(); + return null; } diff --git a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java index 78002d720d7..5831d8470b0 100644 --- a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java +++ b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java @@ -8,17 +8,17 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import forge.AllZone; import forge.Singletons; import forge.control.FControl; import forge.deck.Deck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchStartHelper; +import forge.game.PlayerStartConditions; +import forge.game.player.LobbyPlayer; +import forge.game.player.PlayerType; import forge.gui.SOverlayUtils; import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.controllers.CEditorQuestCardShop; -import forge.gui.match.CMatchUI; import forge.gui.toolbox.FSkin; import forge.quest.QuestController; import forge.quest.QuestEvent; @@ -260,15 +260,14 @@ public class SSubmenuQuestUtil { final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - Singletons.getModel().getMatchState().setGameType(GameType.Quest); - + qData.getChallengesManager().randomizeOpponents(); qData.getDuelsManager().randomizeOpponents(); qData.setCurrentEvent(event); qData.save(); - PlayerStartsGame p1 = new PlayerStartsGame(AllZone.getHumanPlayer(), SSubmenuQuestUtil.getCurrentDeck()); - PlayerStartsGame p2 = new PlayerStartsGame(AllZone.getComputerPlayer(), event.getEventDeck()); + PlayerStartConditions humanStart = new PlayerStartConditions(SSubmenuQuestUtil.getCurrentDeck()); + PlayerStartConditions aiStart = new PlayerStartConditions(event.getEventDeck()); if (qData.getMode() == QuestMode.Fantasy) { int lifeAI = 20; @@ -282,14 +281,21 @@ public class SSubmenuQuestUtil { } } - p1.initialLives = qData.getAssets().getLife(qData.getMode()) + extraLifeHuman; - p1.cardsOnBattlefield = QuestUtil.getHumanStartingCards(qData, event); - p2.initialLives = lifeAI; - p2.cardsOnBattlefield = QuestUtil.getComputerStartingCards(event); + humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman); + humanStart.setCardsOnTable(QuestUtil.getHumanStartingCards(qData, event)); + aiStart.setStartingLife(lifeAI); + aiStart.setCardsOnTable(QuestUtil.getComputerStartingCards(event)); } // End isFantasy - CMatchUI.SINGLETON_INSTANCE.initMatch(event.getIconFilename()); - GameNew.newGame(p1, p2); + MatchStartHelper msh = new MatchStartHelper(); + msh.addPlayer( Singletons.getControl().getLobby().getQuestPlayer(), humanStart ); + + LobbyPlayer aiPlayer = Singletons.getControl().getLobby().findLocalPlayer(PlayerType.COMPUTER, event.getName()); + aiPlayer.setPicture(event.getIconFilename()); + msh.addPlayer( aiPlayer, aiStart ); + + Singletons.getModel().getMatch().initMatch(GameType.Quest, msh.getPlayerMap()); + Singletons.getModel().getMatch().startRound(); return null; } diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java index c7808deb835..44763b3aafa 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java @@ -17,19 +17,18 @@ import javax.swing.SwingWorker; import org.apache.commons.lang3.ArrayUtils; -import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckgenUtil; import forge.deck.generate.GenerateThemeDeck; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; import forge.game.player.PlayerType; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.gui.match.CMatchUI; import forge.gui.toolbox.ExperimentalLabel; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; @@ -319,13 +318,15 @@ public enum CSubmenuConstructed implements ICDoc { Deck humanDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstUserDecks(), PlayerType.HUMAN); Deck aiDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstDecksAI(), PlayerType.COMPUTER); - CMatchUI.SINGLETON_INSTANCE.initMatch(null); - Singletons.getModel().getMatchState().setGameType(GameType.Constructed); - - if (humanDeck != null && aiDeck != null) { - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); - } + MatchStartHelper starter = new MatchStartHelper(); + Lobby lobby = Singletons.getControl().getLobby(); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck); + starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Constructed, starter.getPlayerMap()); + mc.startRound(); + return null; } diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java index 892a8d3433e..4d6958078cf 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java @@ -13,19 +13,21 @@ import forge.AllZone; import forge.Command; import forge.Singletons; import forge.control.FControl; +import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckGroup; -import forge.game.GameNew; import forge.game.GameType; -import forge.game.PlayerStartsGame; +import forge.game.MatchController; +import forge.game.MatchStartHelper; import forge.game.limited.BoosterDraft; import forge.game.limited.CardPoolLimitation; +import forge.game.player.LobbyPlayer; +import forge.game.player.PlayerType; import forge.gui.GuiChoose; import forge.gui.SOverlayUtils; import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.controllers.CEditorDraftingProcess; import forge.gui.framework.ICDoc; -import forge.gui.match.CMatchUI; /** * Controls the draft submenu in the home UI. @@ -44,6 +46,7 @@ public enum CSubmenuDraft implements ICDoc { VSubmenuDraft.SINGLETON_INSTANCE.getBtnStart().setEnabled(true); } }; + private LobbyPlayer[] opponents; /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() @@ -69,7 +72,7 @@ public enum CSubmenuDraft implements ICDoc { }); } }); - } + } /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() @@ -90,16 +93,15 @@ public enum CSubmenuDraft implements ICDoc { private void startGame() { final boolean gauntlet = VSubmenuDraft.SINGLETON_INSTANCE.getRadSingle().isSelected() ? false : true; - - final Deck human = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck(); + final Deck humanDeck = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck(); final int aiIndex = (int) Math.floor(Math.random() * 8); - if (human == null) { + if (humanDeck == null) { JOptionPane.showMessageDialog(null, "No deck selected for human!\r\n(You may need to build a new deck.)", "No deck", JOptionPane.ERROR_MESSAGE); return; - } else if (!human.meetsGameTypeRequirements(GameType.Draft)) { + } else if (!humanDeck.meetsGameTypeRequirements(GameType.Draft)) { JOptionPane.showMessageDialog(null, "The selected deck doesn't have enough cards to play (minimum 40)." + "\r\nUse the deck editor to choose the cards you want before starting.", @@ -110,8 +112,8 @@ public enum CSubmenuDraft implements ICDoc { AllZone.getGauntlet().resetGauntletDraft(); if (gauntlet) { - int rounds = Singletons.getModel().getDecks().getDraft().get(human.getName()).getAiDecks().size(); - AllZone.getGauntlet().launch(rounds, human, GameType.Draft); + int rounds = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()).getAiDecks().size(); + AllZone.getGauntlet().launch(rounds, humanDeck, GameType.Draft); return; } @@ -126,17 +128,20 @@ public enum CSubmenuDraft implements ICDoc { final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(human.getName()); - + DeckGroup opponentDecks = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()); Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); if (aiDeck == null) { throw new IllegalStateException("Draft: Computer deck is null!"); } - - CMatchUI.SINGLETON_INSTANCE.initMatch(null); - Singletons.getModel().getMatchState().setGameType(GameType.Draft); - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), - new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); + + MatchStartHelper starter = new MatchStartHelper(); + starter.addPlayer(Singletons.getControl().getLobby().findLocalPlayer(PlayerType.HUMAN), humanDeck); + starter.addPlayer(opponents[aiIndex], aiDeck); + + MatchController mc = Singletons.getModel().getMatch(); + mc.initMatch(GameType.Draft, starter.getPlayerMap()); + mc.startRound(); + return null; } @@ -180,6 +185,22 @@ public enum CSubmenuDraft implements ICDoc { FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(draft); + opponents = generatePlayers(); + } + + private LobbyPlayer[] generatePlayers() { + Lobby lobby = Singletons.getControl().getLobby(); + LobbyPlayer[] ai = { + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER), + lobby.findLocalPlayer(PlayerType.COMPUTER) + }; + + return ai; } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/match/CMatchUI.java b/src/main/java/forge/gui/match/CMatchUI.java index 3fc77198dfc..18fc7138cec 100644 --- a/src/main/java/forge/gui/match/CMatchUI.java +++ b/src/main/java/forge/gui/match/CMatchUI.java @@ -20,7 +20,6 @@ package forge.gui.match; import java.util.ArrayList; import java.util.List; -import forge.AllZone; import forge.Card; import forge.GameEntity; import forge.game.phase.PhaseType; @@ -46,16 +45,6 @@ public enum CMatchUI implements CardContainer { /** */ SINGLETON_INSTANCE; - /** - * Due to be deprecated with new multiplayer changes. Doublestrike 13-10-12. - * - * @param strAvatarIcon   Filename of non-default avatar icon, if desired. - * - */ - public void initMatch(final String strAvatarIcon) { - this.initMatch(2, 1); - } - /** * Instantiates at a match with a specified number of players * and hands. @@ -63,7 +52,7 @@ public enum CMatchUI implements CardContainer { * @param numFieldPanels int * @param numHandPanels int */ - public void initMatch(int numFieldPanels, int numHandPanels) { + public void initMatch(final List players, Player localPlayer) { // TODO fix for use with multiplayer // Update avatars /*final String[] indices = Singletons.getModel().getPreferences().getPref(FPref.UI_AVATARS).split(","); @@ -71,7 +60,7 @@ public enum CMatchUI implements CardContainer { for (VField view : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { final Image img; // Update AI quest icon - if (i == 1 && Singletons.getModel().getMatchState().getGameType() == GameType.Quest) { + if (i == 1 && Singletons.getModel().getMatch().getGameType() == GameType.Quest) { String filename = ForgeProps.getFile(NewConstants.IMAGE_ICON) + File.separator; if (strAvatarIcon != null) { @@ -94,39 +83,37 @@ public enum CMatchUI implements CardContainer { view.getLblAvatar().getResizeTimer().start(); }*/ - // Instantiate all required field slots (user at 0) + // Instantiate all required field slots (user at 0) <-- that's not guaranteed final List fields = new ArrayList(); - for (int i = 0; i < numFieldPanels; i++) { - switch (i) { - case 0: - fields.add(0, new VField(EDocID.FIELD_0, AllZone.getHumanPlayer())); - fields.get(0).getLayoutControl().initialize(); - break; - case 1: - fields.add(1, new VField(EDocID.FIELD_1, AllZone.getComputerPlayer())); - fields.get(1).getLayoutControl().initialize(); - break; - default: - // A field must be initialized after it's instantiated, to update player info. - // No player, no init. - fields.add(i, new VField(EDocID.valueOf("FIELD_" + i), null)); - } + + fields.add(0, new VField(EDocID.valueOf("FIELD_0"), localPlayer)); + fields.get(0).getLayoutControl().initialize(); + + + int i = 1; + for (Player p : players) { + if (p.equals(localPlayer)) continue; + // A field must be initialized after it's instantiated, to update player info. + // No player, no init. + VField f = new VField(EDocID.valueOf("FIELD_" + i), p); + f.getLayoutControl().initialize(); + fields.add(f); + i++; } + // Instantiate all required hand slots (user at 0) final List hands = new ArrayList(); - for (int i = 0; i < numHandPanels; i++) { - switch (i) { - case 0: - // A hand must be initialized after it's instantiated, to update player info. - // No player, no init. - hands.add(0, new VHand(EDocID.HAND_0, AllZone.getHumanPlayer())); - hands.get(0).getLayoutControl().initialize(); - break; - default: - hands.add(i, new VHand(EDocID.valueOf("HAND_" + i), null)); - } - } + VHand newHand = new VHand(EDocID.HAND_0, localPlayer); + newHand.getLayoutControl().initialize(); + hands.add(newHand); + +// Max: 2+ hand are needed at 2HG (but this is quite far now) - yet it's nice to have this possibility +// for (int i = 0; i < numHandPanels; i++) { +// switch (i) { +// hands.add(i, new VHand(EDocID.valueOf("HAND_" + i), null)); +// } +// } // Replace old instances VMatchUI.SINGLETON_INSTANCE.setFieldViews(fields); diff --git a/src/main/java/forge/gui/match/ControlWinLose.java b/src/main/java/forge/gui/match/ControlWinLose.java index 800ee3f1156..23ef4ea9f74 100644 --- a/src/main/java/forge/gui/match/ControlWinLose.java +++ b/src/main/java/forge/gui/match/ControlWinLose.java @@ -7,15 +7,12 @@ import java.util.List; import javax.swing.JButton; -import forge.AllZone; import forge.Card; import forge.Singletons; import forge.control.FControl; import forge.deck.Deck; -import forge.game.GameNew; -import forge.game.GameSummary; +import forge.game.GameOutcome; import forge.game.GameType; -import forge.game.PlayerStartsGame; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; @@ -68,14 +65,24 @@ public class ControlWinLose { /** Action performed when "continue" button is pressed in default win/lose UI. */ public void actionOnContinue() { SOverlayUtils.hideOverlay(); - startNextRound(); + saveOptions(); + + boolean isAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); + GameType gameType = Singletons.getModel().getMatch().getGameType(); + + //This is called from QuestWinLoseHandler also. If we're in a quest, this is already handled elsewhere + if (isAnte && !gameType.equals(GameType.Quest)) { + executeAnte(); + } + + Singletons.getModel().getMatch().startRound(); } /** Action performed when "restart" button is pressed in default win/lose UI. */ public void actionOnRestart() { - Singletons.getModel().getMatchState().reset(); SOverlayUtils.hideOverlay(); - startNextRound(); + saveOptions(); + Singletons.getModel().getMatch().replayRound(); } /** Action performed when "quit" button is pressed in default win/lose UI. */ @@ -89,9 +96,7 @@ public class ControlWinLose { } // Reset other stuff - Singletons.getModel().getMatchState().reset(); - Singletons.getModel().getPreferences().writeMatchPreferences(); - Singletons.getModel().getPreferences().save(); + saveOptions(); Singletons.getControl().changeState(FControl.HOME_SCREEN); SOverlayUtils.hideOverlay(); } @@ -100,22 +105,9 @@ public class ControlWinLose { * Either continues or restarts a current game. May be overridden for use * with other game modes. */ - public void startNextRound() { - boolean isAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); - GameType gameType = Singletons.getModel().getMatchState().getGameType(); - - //This is called from QuestWinLoseHandler also. If we're in a quest, this is already handled elsewhere - if (isAnte && !gameType.equals(GameType.Quest)) { - executeAnte(); - } - + public void saveOptions() { Singletons.getModel().getPreferences().writeMatchPreferences(); Singletons.getModel().getPreferences().save(); - - CMatchUI.SINGLETON_INSTANCE.initMatch(null); - GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), AllZone.getHumanPlayer().getDeck()), - new PlayerStartsGame(AllZone.getComputerPlayer(), AllZone.getComputerPlayer().getDeck())); - } /** @@ -124,16 +116,13 @@ public class ControlWinLose { * @param cDeck */ private void executeAnte() { - List games = Singletons.getModel().getMatchState().getGamesPlayed(); - if (games.isEmpty()) { - return; - } - GameSummary lastGame = games.get(games.size() - 1); - for (Player p : Singletons.getModel().getGameState().getPlayers()) { - if (!p.getName().equals(lastGame.getWinner())) { - continue; // not a loser - } + List games = Singletons.getModel().getMatch().getPlayedGames(); + if ( games.isEmpty() ) return; + GameOutcome lastGame = games.get(games.size()-1); + for (Player p: Singletons.getModel().getGameState().getPlayers()) { + if (!p.getName().equals(lastGame.getWinner())) continue; // not a loser + // remove all the lost cards from owners' decks List losses = new ArrayList(); for (Player loser : Singletons.getModel().getGameState().getPlayers()) { @@ -142,7 +131,7 @@ public class ControlWinLose { } List compAntes = loser.getCardsIn(ZoneType.Ante); - Deck cDeck = loser.getDeck(); + Deck cDeck = Singletons.getModel().getMatch().getPlayersDeck(loser.getLobbyPlayer()); for (Card c : compAntes) { CardPrinted toRemove = CardDb.instance().getCard(c); @@ -152,10 +141,11 @@ public class ControlWinLose { // offer to winner, if he is human if (p.isHuman()) { - List o = GuiChoose.noneOrMany("Select cards to add to your deck", losses); - if (null != o) { - for (CardPrinted c : o) { - p.getDeck().getMain().add(c); + List chosen = GuiChoose.noneOrMany("Select cards to add to your deck", losses); + if (null != chosen) { + Deck d = Singletons.getModel().getMatch().getPlayersDeck(p.getLobbyPlayer()); + for (CardPrinted c : chosen) { + d.getMain().add(c); } } } diff --git a/src/main/java/forge/gui/match/GauntletWinLose.java b/src/main/java/forge/gui/match/GauntletWinLose.java index 773dab56aa3..9e31c1b298f 100644 --- a/src/main/java/forge/gui/match/GauntletWinLose.java +++ b/src/main/java/forge/gui/match/GauntletWinLose.java @@ -26,9 +26,9 @@ import javax.swing.SwingConstants; import forge.AllZone; import forge.Singletons; +import forge.game.MatchController; import forge.game.limited.GauntletMini; import forge.gui.toolbox.FSkin; -import forge.model.FMatchState; /** * The Win/Lose handler for 'gauntlet' type tournament @@ -47,7 +47,7 @@ public class GauntletWinLose extends ControlWinLose { private JLabel lblTemp1; private JLabel lblTemp2; - private final FMatchState matchState; + private final MatchController matchState; /** * Instantiates a new gauntlet win/lose handler. @@ -58,8 +58,8 @@ public class GauntletWinLose extends ControlWinLose { super(view0); this.view = view0; gauntlet = AllZone.getGauntlet(); - matchState = Singletons.getModel().getMatchState(); - this.wonMatch = matchState.isMatchWonBy(AllZone.getHumanPlayer()); + matchState = Singletons.getModel().getMatch(); + this.wonMatch = matchState.isWonBy(Singletons.getControl().getPlayer().getLobbyPlayer()); } @@ -82,7 +82,7 @@ public class GauntletWinLose extends ControlWinLose { - if (Singletons.getModel().getMatchState().hasWonLastGame(AllZone.getHumanPlayer().getName())) { + if (Singletons.getModel().getMatch().getLastGameOutcome().isWinner(Singletons.getControl().getPlayer().getLobbyPlayer())) { gauntlet.addWin(); } else { diff --git a/src/main/java/forge/gui/match/OtherGauntletWinLose.java b/src/main/java/forge/gui/match/OtherGauntletWinLose.java index e1e93f4d00a..85331e93960 100644 --- a/src/main/java/forge/gui/match/OtherGauntletWinLose.java +++ b/src/main/java/forge/gui/match/OtherGauntletWinLose.java @@ -25,13 +25,14 @@ import javax.swing.JPanel; import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; -import forge.AllZone; +import forge.Singletons; import forge.deck.Deck; +import forge.game.MatchController; +import forge.game.player.LobbyPlayer; import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FSkin; -import forge.model.FMatchState; import forge.model.FModel; /** @@ -57,7 +58,7 @@ public class OtherGauntletWinLose extends ControlWinLose { @Override public final boolean populateCustomPanel() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - final FMatchState matchState = FModel.SINGLETON_INSTANCE.getMatchState(); + final MatchController match = FModel.SINGLETON_INSTANCE.getMatch(); final List lstEventNames = gd.getEventNames(); final List lstDecks = gd.getDecks(); final List lstEventRecords = gd.getEventRecords(); @@ -78,15 +79,14 @@ public class OtherGauntletWinLose extends ControlWinLose { // the player can restart Forge to replay a match. // Pretty sure this can't be fixed until in-game states can be // saved. Doublestrike 07-10-12 - if (matchState.isMatchOver()) { + LobbyPlayer questPlayer = Singletons.getControl().getLobby().getQuestPlayer(); + if (match.isMatchOver()) { // In all cases, update stats. - lstEventRecords.set(gd.getCompleted(), - matchState.countGamesWonBy(AllZone.getHumanPlayer()) - + " - " + matchState.countGamesWonBy(AllZone.getComputerPlayer())); + lstEventRecords.set(gd.getCompleted(), match.getGamesWonBy(questPlayer) + " - " + ( match.getPlayedGames().size() - match.getGamesWonBy(questPlayer) ) ); gd.setCompleted(gd.getCompleted() + 1); // Win match case - if (matchState.isMatchWonBy(AllZone.getHumanPlayer())) { + if (match.isWonBy(questPlayer)) { // Gauntlet complete: Remove save file if (gd.getCompleted() == lstDecks.size()) { lblGraphic = new FLabel.Builder() @@ -112,8 +112,6 @@ public class OtherGauntletWinLose extends ControlWinLose { else { gd.stamp(); GauntletIO.saveGauntlet(gd); - matchState.reset(); - AllZone.getComputerPlayer().setDeck(lstDecks.get(gd.getCompleted())); this.getView().getBtnContinue().setVisible(true); this.getView().getBtnContinue().setEnabled(true); diff --git a/src/main/java/forge/gui/match/QuestWinLoseHandler.java b/src/main/java/forge/gui/match/QuestWinLoseHandler.java index f31fcc02717..c729233857f 100644 --- a/src/main/java/forge/gui/match/QuestWinLoseHandler.java +++ b/src/main/java/forge/gui/match/QuestWinLoseHandler.java @@ -16,8 +16,6 @@ */ package forge.gui.match; -import forge.AllZone; - import javax.swing.JOptionPane; import forge.Card; @@ -30,10 +28,11 @@ import forge.card.UnOpenedProduct; import forge.game.GameEndReason; import forge.game.GameFormat; import forge.game.GameLossReason; -import forge.game.GameNew; -import forge.game.GamePlayerRating; -import forge.game.GameSummary; -import forge.game.PlayerStartsGame; +import forge.game.GameOutcome; +import forge.game.MatchController; +import forge.game.player.LobbyPlayer; +import forge.game.player.PlayerOutcome; +import forge.game.player.PlayerStatistics; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; @@ -42,16 +41,13 @@ import forge.gui.SOverlayUtils; import forge.gui.home.quest.CSubmenuChallenges; import forge.gui.home.quest.CSubmenuDuels; import forge.gui.toolbox.FSkin; +import forge.item.CardDb; import forge.item.CardPrinted; -import forge.model.FMatchState; import forge.properties.ForgePreferences.FPref; import forge.quest.QuestEventChallenge; import forge.quest.QuestController; import forge.quest.QuestEvent; -import forge.quest.QuestMode; -import forge.quest.QuestUtil; import forge.quest.bazaar.QuestItemType; -import forge.quest.data.QuestAssets; import forge.quest.data.QuestPreferences.QPref; import forge.quest.io.ReadPriceList; import forge.util.MyRandom; @@ -63,6 +59,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.TreeMap; import javax.swing.BorderFactory; @@ -92,7 +89,7 @@ public class QuestWinLoseHandler extends ControlWinLose { private static final String CONSTRAINTS_TEXT = "w 95%!,, h 180px!, gap 0 0 0 20px"; private static final String CONSTRAINTS_CARDS = "w 95%!, h 330px!, gap 0 0 0 20px"; - private final transient FMatchState matchState; + private final transient MatchController match; private final transient QuestController qData; private final transient QuestEvent qEvent; @@ -104,53 +101,13 @@ public class QuestWinLoseHandler extends ControlWinLose { public QuestWinLoseHandler(final ViewWinLose view0) { super(view0); this.view = view0; - matchState = Singletons.getModel().getMatchState(); + match = Singletons.getModel().getMatch(); qData = Singletons.getModel().getQuest(); qEvent = qData.getCurrentEvent(); - this.wonMatch = matchState.isMatchWonBy(AllZone.getHumanPlayer()); + this.wonMatch = match.isWonBy(Singletons.getControl().getLobby().getQuestPlayer()); this.isAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); } - /** - *

- * startNextRound. - *

- * Either continues or restarts a current game. - * - */ - @Override - public final void startNextRound() { - Singletons.getModel().getPreferences().writeMatchPreferences(); - Singletons.getModel().getPreferences().save(); - - SOverlayUtils.hideOverlay(); - Singletons.getModel().getQuestPreferences().save(); - - QuestAssets qa = qData.getAssets(); - if (qData.getMode() == QuestMode.Fantasy) { - int extraLife = 0; - - if (qEvent instanceof QuestEventChallenge) { - if (qa.hasItem(QuestItemType.ZEPPELIN)) { - extraLife = 3; - } - } - - CMatchUI.SINGLETON_INSTANCE.initMatch(qEvent.getIconFilename()); - - PlayerStartsGame p1 = new PlayerStartsGame(AllZone.getHumanPlayer(),AllZone.getHumanPlayer().getDeck() ); - p1.cardsOnBattlefield = QuestUtil.getHumanStartingCards(qData, qEvent); - p1.initialLives = qa.getLife(qData.getMode()) + extraLife; - - PlayerStartsGame p2 = new PlayerStartsGame(AllZone.getComputerPlayer(), AllZone.getComputerPlayer().getDeck()); - p2.cardsOnBattlefield = QuestUtil.getComputerStartingCards(qEvent); - p2.initialLives = qEvent instanceof QuestEventChallenge ? ((QuestEventChallenge) qEvent).getAILife() : 20; - - GameNew.newGame( p1, p2 ); - } else { - super.startNextRound(); - } - } /** *

@@ -165,28 +122,29 @@ public class QuestWinLoseHandler extends ControlWinLose { public final boolean populateCustomPanel() { this.getView().getBtnRestart().setVisible(false); qData.getCards().resetNewList(); - + QuestController qc = Singletons.getModel().getQuest(); + LobbyPlayer questPlayer = Singletons.getControl().getLobby().getQuestPlayer(); + if (isAnte) { //do per-game actions - if (matchState.hasWonLastGame(AllZone.getHumanPlayer().getName())) { - if (isAnte) { - final List antes = AllZone.getComputerPlayer().getCardsIn(ZoneType.Ante); - final List antesPrinted = Singletons.getModel().getMatchState().addAnteWon(antes); - this.anteWon(antesPrinted); - + boolean isHumanWinner = match.isWonBy(questPlayer); + final List anteCards = new ArrayList(); + for( Player p : Singletons.getModel().getGameState().getPlayers() ) { + if (p.getLobbyPlayer().equals(questPlayer) == isHumanWinner) continue; + for(Card c : p.getCardsIn(ZoneType.Ante)) + anteCards.add(CardDb.instance().getCard(c)); } - } else { - if (isAnte) { - final List antes = AllZone.getHumanPlayer().getCardsIn(ZoneType.Ante); - final List antesPrinted = Singletons.getModel().getMatchState().addAnteLost(antes); - for (final CardPrinted ante : antesPrinted) { - //the last param here (should) determine if this is added to the Card Shop - Singletons.getModel().getQuest().getCards().sellCard(ante, 0, false); - } - this.anteLost(antesPrinted); + + if (isHumanWinner) { + qc.getCards().addAllCards(anteCards); + this.anteWon(anteCards); + } else { + for(CardPrinted c : anteCards) + qc.getCards().loseCard(c); + this.anteLost(anteCards); } } - if (!matchState.isMatchOver()) { + if (!match.isMatchOver()) { this.getView().getBtnQuit().setText("Quit (15 Credits)"); return isAnte; } else { @@ -244,10 +202,6 @@ public class QuestWinLoseHandler extends ControlWinLose { } } - // Add any antes won this match (regardless of Match Win/Lose to Card Pool - // Note: Antes lost have already been remove from decks. - Singletons.getModel().getMatchState().addAnteWonToCardPool(); - return true; } @@ -329,7 +283,6 @@ public class QuestWinLoseHandler extends ControlWinLose { qData.getAchievements().addChallengesPlayed(); } - matchState.reset(); CSubmenuDuels.SINGLETON_INSTANCE.update(); CSubmenuChallenges.SINGLETON_INSTANCE.update(); @@ -384,41 +337,51 @@ public class QuestWinLoseHandler extends ControlWinLose { sb.append(diff + " opponent: " + credBase + " credits.
"); // Gameplay bonuses (for each game win) boolean hasNeverLost = true; - final Player computer = AllZone.getComputerPlayer(); - for (final GameSummary game : matchState.getGamesPlayed()) { - if (game.isWinner(computer.getName())) { + + LobbyPlayer localHuman = Singletons.getControl().getLobby().getQuestPlayer(); + for (final GameOutcome game : match.getPlayedGames()) { + if (!game.isWinner(localHuman)) { hasNeverLost = false; continue; // no rewards for losing a game } // Alternate win - final GamePlayerRating aiRating = game.getPlayerRating(computer.getName()); - final GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName()); - final GameLossReason whyAiLost = aiRating.getLossReason(); - final int altReward = this.getCreditsRewardForAltWin(whyAiLost); - - if (altReward > 0) { - String winConditionName = "Unknown (bug)"; - if (game.getWinCondition() == GameEndReason.WinsGameSpellEffect) { - winConditionName = game.getWinSpellEffect(); - } else { - switch (whyAiLost) { - case Poisoned: - winConditionName = "Poison"; - break; - case Milled: - winConditionName = "Milled"; - break; - case SpellEffect: - winConditionName = aiRating.getLossSpellName(); - break; - default: - break; - } + +// final PlayerStatistics aiRating = game.getStatistics(computer.getName()); + PlayerStatistics humanRating = null; + for(Entry aiRating : game ) { + if( aiRating.getValue().equals(localHuman)) { + humanRating = aiRating.getValue(); + continue; } + + final PlayerOutcome outcome = aiRating.getValue().getOutcome(); + final GameLossReason whyAiLost = outcome.lossState; + final int altReward = this.getCreditsRewardForAltWin(whyAiLost); - credGameplay += 50; - sb.append(String.format("Alternate win condition: %s! " + "Bonus: %d credits.
", - winConditionName, 50)); + if (altReward > 0) { + String winConditionName = "Unknown (bug)"; + if (game.getWinCondition() == GameEndReason.WinsGameSpellEffect) { + winConditionName = game.getWinSpellEffect(); + } else { + switch (whyAiLost) { + case Poisoned: + winConditionName = "Poison"; + break; + case Milled: + winConditionName = "Milled"; + break; + case SpellEffect: + winConditionName = outcome.loseConditionSpell; + break; + default: + break; + } + } + + credGameplay += 50; + sb.append(String.format("Alternate win condition: %s! " + "Bonus: %d credits.
", + winConditionName, 50)); + } } // Mulligan to zero final int cntCardsHumanStartedWith = humanRating.getOpeningHandSize(); @@ -945,6 +908,8 @@ public class QuestWinLoseHandler extends ControlWinLose { * @return int */ private int getCreditsRewardForAltWin(final GameLossReason whyAiLost) { + if ( null == whyAiLost) // Felidar, Helix Pinnacle, etc. + return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED); switch (whyAiLost) { case LifeReachedZero: return 0; // nothing special here, ordinary kill @@ -952,8 +917,6 @@ public class QuestWinLoseHandler extends ControlWinLose { return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_MILLED); case Poisoned: return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_POISON); - case DidNotLoseYet: // Felidar, Helix Pinnacle, etc. - return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED); case SpellEffect: // Door to Nothingness, etc. return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED); default: diff --git a/src/main/java/forge/gui/match/ViewWinLose.java b/src/main/java/forge/gui/match/ViewWinLose.java index ece12a3ed78..72f2a497af5 100644 --- a/src/main/java/forge/gui/match/ViewWinLose.java +++ b/src/main/java/forge/gui/match/ViewWinLose.java @@ -12,9 +12,8 @@ import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Singletons; -import forge.game.GameType; -import forge.game.phase.PhaseHandler; -import forge.game.player.Player; +import forge.game.MatchController; +import forge.game.player.LobbyPlayer; import forge.gui.SOverlayUtils; import forge.gui.toolbox.FButton; import forge.gui.toolbox.FLabel; @@ -22,7 +21,6 @@ import forge.gui.toolbox.FOverlay; import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FTextArea; -import forge.model.FMatchState; import forge.properties.ForgeProps; import forge.properties.NewConstants.Lang.GuiWinLose.WinLoseText; @@ -38,7 +36,7 @@ public class ViewWinLose { /** */ public ViewWinLose() { final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel(); - final FMatchState matchState = Singletons.getModel().getMatchState(); + final MatchController match = Singletons.getModel().getMatch(); final JPanel pnlLeft = new JPanel(); final JPanel pnlRight = new JPanel(); @@ -52,23 +50,26 @@ public class ViewWinLose { btnRestart = new FButton(); btnQuit = new FButton(); - final Player human = Singletons.getControl().getPlayer(); + final LobbyPlayer human = Singletons.getControl().getPlayer().getLobbyPlayer(); // Control of the win/lose is handled differently for various game modes. - ControlWinLose control; - if (matchState.getGameType() == GameType.Quest) { - control = new QuestWinLoseHandler(this); + ControlWinLose control = null; + switch (Singletons.getModel().getMatch().getGameType()) { + case Quest: + control = new QuestWinLoseHandler(this); + break; + case Draft: + if (!AllZone.getGauntlet().isGauntletDraft()) break; + case Sealed: + control = new GauntletWinLose(this); + break; + case Gauntlet: + control = new OtherGauntletWinLose(this); + break; } - else if (matchState.getGameType() == GameType.Sealed - || (matchState.getGameType() == GameType.Draft && AllZone.getGauntlet().isGauntletDraft())) { - control = new GauntletWinLose(this); - } - else if (matchState.getGameType() == GameType.Gauntlet) { - control = new OtherGauntletWinLose(this); - } - else { + if( null == control) control = new ControlWinLose(this); - } + pnlLeft.setOpaque(false); pnlRight.setOpaque(false); @@ -94,24 +95,22 @@ public class ViewWinLose { btnQuit.setText(ForgeProps.getLocalized(WinLoseText.QUIT)); btnQuit.setFont(FSkin.getFont(22)); - // End game and set state of "continue" button - PhaseHandler.setGameBegins(0); - if (matchState.isMatchOver()) { + if (match.isMatchOver()) { this.getBtnContinue().setEnabled(false); this.getBtnQuit().grabFocus(); } // Show Wins and Loses - final int humanWins = matchState.countGamesWonBy(human); - final int humanLosses = matchState.getGamesPlayedCount() - humanWins; + final int humanWins = match.getGamesWonBy(human); + final int humanLosses = match.getPlayedGames().size() - humanWins; lblStats.setText(ForgeProps.getLocalized(WinLoseText.WON) + humanWins + ForgeProps.getLocalized(WinLoseText.LOST) + humanLosses); // Show "You Won" or "You Lost" - if (matchState.hasWonLastGame(human.getName())) { + if (match.getLastGameOutcome().isWinner(human)) { lblTitle.setText(ForgeProps.getLocalized(WinLoseText.WIN)); } else { lblTitle.setText(ForgeProps.getLocalized(WinLoseText.LOSE)); diff --git a/src/main/java/forge/gui/match/controllers/CAntes.java b/src/main/java/forge/gui/match/controllers/CAntes.java index 317c8532b22..a8537ea6bc7 100644 --- a/src/main/java/forge/gui/match/controllers/CAntes.java +++ b/src/main/java/forge/gui/match/controllers/CAntes.java @@ -34,5 +34,4 @@ public enum CAntes implements ICDoc { @Override public void update() { } - } diff --git a/src/main/java/forge/gui/match/controllers/CCombat.java b/src/main/java/forge/gui/match/controllers/CCombat.java index cd11686b3a0..0acf8fe8d68 100644 --- a/src/main/java/forge/gui/match/controllers/CCombat.java +++ b/src/main/java/forge/gui/match/controllers/CCombat.java @@ -36,5 +36,4 @@ public enum CCombat implements ICDoc { public void update() { VCombat.SINGLETON_INSTANCE.updateCombat(""); } - } diff --git a/src/main/java/forge/gui/match/controllers/CDetail.java b/src/main/java/forge/gui/match/controllers/CDetail.java index 4cf401b6523..d9fa14fd50f 100644 --- a/src/main/java/forge/gui/match/controllers/CDetail.java +++ b/src/main/java/forge/gui/match/controllers/CDetail.java @@ -37,7 +37,7 @@ public enum CDetail implements ICDoc { SINGLETON_INSTANCE; private Card currentCard = null; - private InventoryItem item = null; + //private InventoryItem item = null; /** * Shows card details and/or picture in sidebar cardview tabber. @@ -45,7 +45,7 @@ public enum CDetail implements ICDoc { * @param c   Card object */ public void showCard(final Card c) { - this.item = null; + //this.item = null; this.currentCard = c; VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(c != null && c.isDoubleFaced() ? true : false); VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(c); @@ -54,7 +54,7 @@ public enum CDetail implements ICDoc { public void showCard(InventoryItem item) { // TODO If we want to display an Items Written Text in the Detail Panel we need to add something into CardDetailPanel - this.item = item; + //this.item = item; this.currentCard = null; VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false); VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(null); diff --git a/src/main/java/forge/gui/match/controllers/CDock.java b/src/main/java/forge/gui/match/controllers/CDock.java index 6594c0c7b33..629f1e36a07 100644 --- a/src/main/java/forge/gui/match/controllers/CDock.java +++ b/src/main/java/forge/gui/match/controllers/CDock.java @@ -137,7 +137,7 @@ public enum CDock implements ICDoc { * View deck list. */ private void viewDeckList() { - showDeck(Singletons.getControl().getPlayer().getDeck()); + showDeck(Singletons.getModel().getMatch().getPlayersDeck(Singletons.getControl().getPlayer().getLobbyPlayer())); } /** Attack with everyone. */ @@ -290,4 +290,5 @@ public enum CDock implements ICDoc { @Override public void update() { } + } diff --git a/src/main/java/forge/gui/match/controllers/CLog.java b/src/main/java/forge/gui/match/controllers/CLog.java index 328351be8d9..679adfb746e 100644 --- a/src/main/java/forge/gui/match/controllers/CLog.java +++ b/src/main/java/forge/gui/match/controllers/CLog.java @@ -3,8 +3,8 @@ package forge.gui.match.controllers; import java.util.Observable; import java.util.Observer; -import forge.AllZone; import forge.Command; +import forge.game.GameState; import forge.gui.framework.ICDoc; import forge.gui.match.views.VLog; @@ -31,7 +31,11 @@ public enum CLog implements ICDoc, Observer { */ @Override public void initialize() { - AllZone.getGameLog().addObserver(this); + + } + + public void subscribe(GameState currentGame) { + currentGame.getGameLog().addObserver(this); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/match/controllers/CMessage.java b/src/main/java/forge/gui/match/controllers/CMessage.java index 949aa12b5da..caede133f39 100644 --- a/src/main/java/forge/gui/match/controllers/CMessage.java +++ b/src/main/java/forge/gui/match/controllers/CMessage.java @@ -22,6 +22,8 @@ import java.awt.event.ActionListener; import forge.Command; import forge.Singletons; +import forge.game.GameState; +import forge.game.MatchController; import forge.gui.GuiInput; import forge.gui.framework.ICDoc; import forge.gui.framework.SDisplayUtil; @@ -36,7 +38,7 @@ public enum CMessage implements ICDoc { /** */ SINGLETON_INSTANCE; - private final GuiInput inputControl = new GuiInput(); + private GuiInput inputControl = new GuiInput(); private final ActionListener actCancel = new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { @@ -59,6 +61,10 @@ public enum CMessage implements ICDoc { } }; + public void subscribe(GameState game) { + inputControl.subscribe(game); + } + @Override public void initialize() { VMessage.SINGLETON_INSTANCE.getBtnCancel().removeActionListener(actCancel); @@ -82,13 +88,15 @@ public enum CMessage implements ICDoc { VMessage.SINGLETON_INSTANCE.getTarMessage().setText(s0); } - /** Updates counter label in message area. */ - public void updateGameInfo() { + /** Updates counter label in message area. + * @param match + * @param gameState */ + public void updateGameInfo(MatchController match) { VMessage.SINGLETON_INSTANCE.getLblGames().setText( - Singletons.getModel().getMatchState().getGameType().toString() + ": Game #" - + (Singletons.getModel().getMatchState().getGamesPlayedCount() + 1) - + " of " + Singletons.getModel().getMatchState().getGamesPerMatch() - + ", turn " + Singletons.getModel().getGameSummary().getLastTurnNumber()); + match.getGameType().toString() + ": Game #" + + (match.getPlayedGames().size() + 1) + + " of " + match.getGamesPerMatch() + + ", turn " + match.getCurrentGame().getTurnNumber()); } /** Flashes animation on input panel if play is currently waiting on input. */ diff --git a/src/main/java/forge/gui/match/controllers/CPlayers.java b/src/main/java/forge/gui/match/controllers/CPlayers.java index 2694783da32..971efc2cdd4 100644 --- a/src/main/java/forge/gui/match/controllers/CPlayers.java +++ b/src/main/java/forge/gui/match/controllers/CPlayers.java @@ -1,7 +1,8 @@ package forge.gui.match.controllers; -import forge.AllZone; import forge.Command; +import forge.Singletons; +import forge.game.player.Player; import forge.gui.framework.ICDoc; import forge.gui.match.views.VPlayers; @@ -35,8 +36,9 @@ public enum CPlayers implements ICDoc { */ @Override public void update() { - VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(AllZone.getComputerPlayer()); - VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(AllZone.getHumanPlayer()); + for(Player p : Singletons.getModel().getGameState().getPlayers()) + VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(p); + VPlayers.SINGLETON_INSTANCE.updateStormLabel(); } diff --git a/src/main/java/forge/gui/match/controllers/CStack.java b/src/main/java/forge/gui/match/controllers/CStack.java index 9663bffc38f..e437d775059 100644 --- a/src/main/java/forge/gui/match/controllers/CStack.java +++ b/src/main/java/forge/gui/match/controllers/CStack.java @@ -3,8 +3,8 @@ package forge.gui.match.controllers; import java.util.Observable; import java.util.Observer; -import forge.AllZone; import forge.Command; +import forge.game.GameState; import forge.gui.framework.EDocID; import forge.gui.framework.ICDoc; import forge.gui.framework.SDisplayUtil; @@ -33,9 +33,12 @@ public enum CStack implements ICDoc, Observer { */ @Override public void initialize() { - AllZone.getStack().addObserver(this); } + public void subscribe(GameState currentGame) { + currentGame.getStack().addObserver(this); + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#update() */ diff --git a/src/main/java/forge/gui/match/nonsingleton/CEmptyDoc.java b/src/main/java/forge/gui/match/nonsingleton/CEmptyDoc.java index 4c378fa2aba..2956de00745 100644 --- a/src/main/java/forge/gui/match/nonsingleton/CEmptyDoc.java +++ b/src/main/java/forge/gui/match/nonsingleton/CEmptyDoc.java @@ -30,5 +30,4 @@ public class CEmptyDoc implements ICDoc { @Override public void update() { } - } diff --git a/src/main/java/forge/gui/match/nonsingleton/VField.java b/src/main/java/forge/gui/match/nonsingleton/VField.java index a28f839395d..9842ff23650 100644 --- a/src/main/java/forge/gui/match/nonsingleton/VField.java +++ b/src/main/java/forge/gui/match/nonsingleton/VField.java @@ -33,7 +33,6 @@ import javax.swing.border.LineBorder; import javax.swing.border.MatteBorder; import net.miginfocom.swing.MigLayout; -import forge.AllZone; import forge.card.cardfactory.CardFactoryUtil; import forge.card.mana.ManaPool; import forge.game.player.Player; @@ -122,8 +121,7 @@ public class VField implements IVDoc { // TODO player is hard-coded into tabletop...should be dynamic // (haven't looked into it too deeply). Doublestrike 12-04-12 - tabletop = new PlayArea(scroller, - AllZone.getComputerPlayer().equals(player) ? true : false); + tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1 ); control = new CField(player, this); diff --git a/src/main/java/forge/model/FMatchState.java b/src/main/java/forge/model/FMatchState.java deleted file mode 100644 index 5c3503f5070..00000000000 --- a/src/main/java/forge/model/FMatchState.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * 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 . - */ -package forge.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import forge.Card; -import forge.Singletons; -import forge.game.GameSummary; -import forge.game.GameType; -import forge.game.player.Player; -import forge.item.CardDb; -import forge.item.CardPrinted; - -/** - * Represents state of match as a whole - that is, not - * single games, but the entire set. - * - * @author Forge - * @version $Id$ - */ - -public class FMatchState { - private GameType gameType = GameType.Constructed; - private int gamesPerMatch = 3; - private int gamesToWinMatch = 2; - - private final List gamesPlayed = new ArrayList(); - - private final List antesWon = new ArrayList(); - private final List antesLost = new ArrayList(); - - // ArrayList - - /** - * Adds the game played. - * - * @param completedGame - * the completed game - */ - public final void addGamePlayed(final GameSummary completedGame) { - this.gamesPlayed.add(completedGame); - } - - /** - * Gets the games played. - * - * @return the games played - */ - public final List getGamesPlayed() { - return this.gamesPlayed; - } - - /** @return int */ - public int getGamesPerMatch() { - return gamesPerMatch; - } - - /** @return int */ - public int getGamesToWinMatch() { - return gamesToWinMatch; - } - - /** - * Gets the games played count. - * - * @return java.lang.Integer - */ - public final Integer getGamesPlayedCount() { - return this.gamesPlayed.size(); - } - - /** - * Checks for won last game. - * - * @param playerName - * the player name - * @return true, if successful - */ - public final boolean hasWonLastGame(final String playerName) { - final int iLastGame = this.gamesPlayed.size() - 1; - return iLastGame >= 0 ? this.gamesPlayed.get(iLastGame).isWinner(playerName) : false; - } - - /** - * Checks if is match over. - * - * @return true, if match is over - */ - public final boolean isMatchOver() { - int totalGames = 0; - - final Map winsCount = new HashMap(); - for (final GameSummary game : this.gamesPlayed) { - final String winner = game.getWinner(); - final Integer boxedWins = winsCount.get(winner); - final int wins = boxedWins == null ? 0 : boxedWins.intValue(); - winsCount.put(winner, wins + 1); - totalGames++; - } - - int maxWins = 0; - for (final Integer win : winsCount.values()) { - maxWins = Math.max(maxWins, win); - } - - return (maxWins >= this.gamesToWinMatch) || (totalGames >= this.gamesPerMatch); - } - - /** - * Count games won by. - * - * @param player {@link forge.game.Player} - * @return java.lang.Integer - */ - public final int countGamesWonBy(final Player player) { - int wins = 0; - for (final GameSummary game : this.gamesPlayed) { - if (game.isWinner(player.toString())) { - wins++; - } - } - return wins; - } - - /** - * Checks if is match won by. - * - * @param player0 - * the player - * @return true, if is match won by - */ - public final boolean isMatchWonBy(final Player player0) { - return this.countGamesWonBy(player0) >= this.gamesToWinMatch; - } - - /** - * Adds a List to the antes that have already been won this match. - * - * @param antes cards won in ante - * @return the list - * @since 1.2.3 - */ - public final List addAnteWon(final List antes) { - List antesPrinted = new ArrayList(); - for (Card ante : antes) { - CardPrinted cp = CardDb.instance().getCard(ante.getName(), ante.getCurSetCode()); - antesWon.add(cp); - antesPrinted.add(cp); - } - return antesPrinted; - } - - /** - * Gets a list of all cards won in ante during this match. - * - * @return a list of cards won in ante this match - */ - public final List getAnteWon() { - return antesWon; - } - - /** - * Adds the ante cards won this match to the CardPool (and they get marker as NEW). - * - * @since 1.2.3 - */ - public final void addAnteWonToCardPool() { - Singletons.getModel().getQuest().getCards().addAllCards(antesWon); - } - - /** - * Adds a List to the antes that have already been lost this match. - * - * @param antes cards lost in ante - * @return the list - * @since 1.2.3 - */ - public final List addAnteLost(final List antes) { - List antesPrinted = new ArrayList(); - for (Card ante : antes) { - CardPrinted cp = CardDb.instance().getCard(ante.getName(), ante.getCurSetCode()); - antesLost.add(cp); - antesPrinted.add(cp); - } - return antesPrinted; - } - - /** - * Reset. - */ - public final void reset() { - this.gamesPlayed.clear(); - this.antesWon.clear(); - this.antesLost.clear(); - } - - /** @return {@link forge.game.GameType} */ - public GameType getGameType() { - return gameType; - } - - /** @param gameType0 {@link forge.game.GameType} */ - public void setGameType(final GameType gameType0) { - gameType = gameType0; - } -} diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index d202762041b..913a31d2dc9 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -38,11 +38,8 @@ import forge.control.input.InputControl; import forge.deck.CardCollections; import forge.error.ExceptionHandler; import forge.game.GameState; -import forge.game.GameSummary; -import forge.game.player.ComputerAIGeneral; -import forge.game.player.ComputerAIInput; -import forge.game.player.Player; -import forge.game.player.PlayerType; +import forge.game.MatchController; +import forge.game.player.LobbyPlayer; import forge.gauntlet.GauntletData; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; @@ -50,7 +47,6 @@ import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.quest.QuestController; import forge.quest.data.QuestPreferences; -import forge.util.Aggregates; import forge.util.FileUtil; import forge.util.HttpUtil; import forge.util.IStorageView; @@ -80,11 +76,11 @@ public enum FModel { private final GameAction gameAction; private final QuestPreferences questPreferences; private final ForgePreferences preferences; - private final GameState gameState; - private final FMatchState matchState; + private GameState gameState; private GauntletData gauntletData; private QuestController quest = null; + private final MatchController match; private final EditionCollection editions; private final FormatCollection formats; @@ -133,8 +129,6 @@ public enum FModel { } this.gameAction = new GameAction(); - this.gameState = new GameState(); - this.matchState = new FMatchState(); this.questPreferences = new QuestPreferences(); this.gauntletData = new GauntletData(); @@ -146,13 +140,12 @@ public enum FModel { this.blocks = new StorageView(new CardBlock.Reader("res/blockdata/blocks.txt", editions)); this.fantasyBlocks = new StorageView(new CardBlock.Reader("res/blockdata/fantasyblocks.txt", editions)); + this.match = new MatchController(); // TODO - there's got to be a better place for this...oblivion? Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); // Instantiate AI AllZone.setInputControl(new InputControl(FModel.this)); - Player computerPlayer = Aggregates.firstFieldEquals(gameState.getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER); - AllZone.getInputControl().setComputer(new ComputerAIInput(new ComputerAIGeneral(computerPlayer))); /// Wrong direction here. It is computer that lives inside player, not a player in computer testNetworkConnection(); @@ -360,25 +353,6 @@ public enum FModel { return this.gameState; } - /** - * Gets the match state model - that is, the data stored over multiple - * games. - * - * @return {@link forge.model.FMatchState} - */ - public final FMatchState getMatchState() { - return this.matchState; - } - - /** - * Gets the game summary. - * - * @return {@link forge.game.GameSummary} - */ - public final GameSummary getGameSummary() { - return this.gameState.getGameSummary(); - } - /** * TODO: Write javadoc for this method. * @@ -444,4 +418,17 @@ public enum FModel { public void setGauntletData(GauntletData data0) { this.gauntletData = data0; } + + public MatchController getMatch() { + return match; + } + + /** + * TODO: Write javadoc for this method. + * @param players + */ + public GameState newGame(Iterable players) { + gameState = new GameState(players); + return gameState; + } } diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java index ae9b3cd7e44..eab19077584 100644 --- a/src/main/java/forge/quest/QuestUtilCards.java +++ b/src/main/java/forge/quest/QuestUtilCards.java @@ -84,9 +84,6 @@ public final class QuestUtilCards { return pool; } - // adds 11 cards, to the current card pool - // (I chose 11 cards instead of 15 in order to make things more challenging) - /** *

* addCards. @@ -261,6 +258,10 @@ public final class QuestUtilCards { this.sellCard(card, price, true); } + public void loseCard(final CardPrinted card) { + this.sellCard(card, 0, false); + } + /** * Sell card. * @@ -271,7 +272,7 @@ public final class QuestUtilCards { * @param addToShop * true if this card should be added to the shop, false otherwise */ - public void sellCard(final CardPrinted card, final int price, final boolean addToShop) { + private void sellCard(final CardPrinted card, final int price, final boolean addToShop) { if (price > 0) { this.qa.setCredits(this.qa.getCredits() + price); } diff --git a/src/main/java/forge/view/FView.java b/src/main/java/forge/view/FView.java index 42bd66ea438..ca4d0bdb340 100644 --- a/src/main/java/forge/view/FView.java +++ b/src/main/java/forge/view/FView.java @@ -22,7 +22,6 @@ import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; import forge.gui.framework.SLayoutConstants; -import forge.gui.home.CHomeUI; import forge.gui.home.VHomeUI; import forge.gui.match.TargetingOverlay; import forge.gui.match.VMatchUI;