Removed hardcoded players

This commit is contained in:
Maxmtg
2012-10-18 08:20:29 +00:00
parent 7beb043d20
commit 50620c07e2
67 changed files with 1537 additions and 1591 deletions

12
.gitattributes vendored
View File

@@ -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/ControlBazaarUI.java -text
src/main/java/forge/control/FControl.java -text src/main/java/forge/control/FControl.java -text
src/main/java/forge/control/KeyboardShortcuts.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/RestartUtil.java -text
src/main/java/forge/control/bazaar/ControlStall.java -text src/main/java/forge/control/bazaar/ControlStall.java -text
src/main/java/forge/control/bazaar/package-info.java svneol=native#text/plain 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/GameFormat.java -text
src/main/java/forge/game/GameLossReason.java -text src/main/java/forge/game/GameLossReason.java -text
src/main/java/forge/game/GameNew.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/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/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/BoosterDeck.java -text
src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain
src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain src/main/java/forge/game/limited/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/ComputerUtilAttack.java svneol=native#text/plain
src/main/java/forge/game/player/ComputerUtilBlock.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/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/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/PlayerType.java svneol=native#text/plain
src/main/java/forge/game/player/PlayerUtil.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 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/TournamentPack.java -text
src/main/java/forge/item/package-info.java -text src/main/java/forge/item/package-info.java -text
src/main/java/forge/model/BuildInfo.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/FModel.java svneol=native#text/plain
src/main/java/forge/model/MultipleForgeJarsFoundError.java -text src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
src/main/java/forge/model/package-info.java svneol=native#text/plain src/main/java/forge/model/package-info.java svneol=native#text/plain

View File

@@ -17,8 +17,6 @@
*/ */
package forge; package forge;
import java.util.List;
import forge.card.cardfactory.CardFactory; import forge.card.cardfactory.CardFactory;
import forge.card.cardfactory.CardFactoryInterface; import forge.card.cardfactory.CardFactoryInterface;
import forge.card.replacement.ReplacementHandler; import forge.card.replacement.ReplacementHandler;
@@ -29,13 +27,11 @@ import forge.game.limited.GauntletMini;
import forge.game.phase.Combat; import forge.game.phase.Combat;
import forge.game.phase.EndOfTurn; import forge.game.phase.EndOfTurn;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.game.zone.MagicStack; import forge.game.zone.MagicStack;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.properties.ForgeProps; import forge.properties.ForgeProps;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.util.Aggregates;
/** /**
@@ -75,40 +71,6 @@ public final class AllZone {
// shared between Input_Attack, Input_Block, Input_CombatDamage , // shared between Input_Attack, Input_Block, Input_CombatDamage ,
// InputState_Computer // InputState_Computer
/**
* <p>
* getHumanPlayer.
* </p>
*
* 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);
}
/**
* <p>
* getComputerPlayer.
* </p>
*
* Will eventually be marked deprecated.
*
* @return a {@link forge.game.player.Player} object.
* @since 1.0.15
*/
@Deprecated
public static Player getComputerPlayer() {
List<Player> players = Singletons.getModel().getGameState().getPlayers();
return Aggregates.firstFieldEquals(players, Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER);
}
/** /**
* <p> * <p>
* getGauntletData. * getGauntletData.

View File

@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.CardPredicates.Presets; import forge.CardPredicates.Presets;
import forge.game.player.Player; import forge.game.player.Player;
@@ -47,33 +48,24 @@ public abstract class AllZoneUtil {
* @return a List<Card> with all cards currently in a graveyard * @return a List<Card> with all cards currently in a graveyard
*/ */
public static List<Card> getCardsIn(final ZoneType zone) { public static List<Card> getCardsIn(final ZoneType zone) {
final List<Card> cards = new ArrayList<Card>();
getCardsIn(zone, cards);
return cards;
}
private static void getCardsIn(final ZoneType zone, final List<Card> cards) {
if (zone == ZoneType.Stack) { if (zone == ZoneType.Stack) {
cards.addAll(AllZone.getStackZone().getCards()); return AllZone.getStackZone().getCards();
} else { } else {
List<Card> cards = null;
for (final Player p : Singletons.getModel().getGameState().getPlayers()) { for (final Player p : Singletons.getModel().getGameState().getPlayers()) {
if ( cards == null )
cards = p.getZone(zone).getCards();
else
cards.addAll(p.getZone(zone).getCards()); cards.addAll(p.getZone(zone).getCards());
} }
return cards;
} }
} }
public static List<Card> getCardsIn(final Iterable<ZoneType> zones) { public static List<Card> getCardsIn(final Iterable<ZoneType> zones) {
final List<Card> cards = new ArrayList<Card>(); final List<Card> cards = new ArrayList<Card>();
for (final ZoneType z : zones) { for (final ZoneType z : zones) {
getCardsIn(z, cards); cards.addAll(getCardsIn(z));
}
return cards;
}
public static List<Card> getCardsIn(final ZoneType[] zones) {
final List<Card> cards = new ArrayList<Card>();
for (final ZoneType z : zones) {
getCardsIn(z, cards);
} }
return cards; return cards;
} }
@@ -182,11 +174,10 @@ public abstract class AllZoneUtil {
* @return true is the card is in play, false otherwise * @return true is the card is in play, false otherwise
*/ */
public static boolean isCardInPlay(final String cardName) { public static boolean isCardInPlay(final String cardName) {
for (Card card : AllZoneUtil.getCardsIn(ZoneType.Battlefield)) { for (final Player p : Singletons.getModel().getGameState().getPlayers()) {
if (card.getName().equals(cardName)) { if (isCardInPlay(cardName, p))
return true; return true;
} }
}
return false; return false;
} }
@@ -200,12 +191,7 @@ public abstract class AllZoneUtil {
* @return true if that player has that card in play, false otherwise * @return true if that player has that card in play, false otherwise
*/ */
public static boolean isCardInPlay(final String cardName, final Player player) { public static boolean isCardInPlay(final String cardName, final Player player) {
for (Card card : player.getCardsIn(ZoneType.Battlefield)) { return Iterables.any(player.getZone(ZoneType.Battlefield), CardPredicates.nameEquals(cardName));
if (card.getName().equals(cardName)) {
return true;
}
}
return false;
} }
// ////////////// getting all cards of a given color // ////////////// getting all cards of a given color

View File

@@ -26,6 +26,7 @@ import java.util.List;
import javax.swing.JFrame; import javax.swing.JFrame;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.card.abilityfactory.AbilityFactory; import forge.card.abilityfactory.AbilityFactory;
import forge.card.abilityfactory.AbilityFactoryAttach; import forge.card.abilityfactory.AbilityFactoryAttach;
@@ -51,8 +52,8 @@ import forge.card.trigger.TriggerType;
import forge.control.input.InputPayManaCost; import forge.control.input.InputPayManaCost;
import forge.control.input.InputPayManaCostUtil; import forge.control.input.InputPayManaCostUtil;
import forge.game.GameEndReason; import forge.game.GameEndReason;
import forge.game.GameSummary; import forge.game.GameLossReason;
import forge.game.phase.PhaseHandler; import forge.game.GameState;
import forge.game.player.ComputerUtil; import forge.game.player.ComputerUtil;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
@@ -896,54 +897,43 @@ public class GameAction {
* *
* @return a boolean. * @return a boolean.
*/ */
public final boolean checkEndGameState() { public final boolean checkEndGameState(final GameState game) {
// if game is already over return true // if game is already over return true
if (Singletons.getModel().getGameState().isGameOver()) { if (game.isGameOver()) {
return true; 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 GameEndReason reason = null;
if (human.hasWon() || computer.hasLost()) { // award loses as SBE
humanWins = true; for (Player p : game.getPlayers() ) {
p.checkLoseCondition(); // this will set appropriate outcomes
}
if (human.getAltWin()) { // Has anyone won by spelleffect?
game.end(GameEndReason.WinsGameSpellEffect, human.getName(), human.getWinConditionSource()); for (Player p : game.getPlayers() ) {
} else { if( p.hasWon() ) { // then the rest have lost!
game.end(GameEndReason.AllOpponentsLost, human.getName(), null); 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;
} }
} }
if (computer.hasWon() || human.hasLost()) { // still unclear why this has not caught me conceding
if (humanWins) { if ( reason == null && Iterables.size(Iterables.filter(game.getPlayers(), Player.Predicates.NOT_LOST)) == 1 )
// both players won/lost at the same time. {
game.end(GameEndReason.Draw, null, null); reason = GameEndReason.AllOpponentsLost;
} else {
computerWins = true;
if (computer.getAltWin()) {
game.end(GameEndReason.WinsGameSpellEffect, computer.getName(), computer.getWinConditionSource());
} else {
game.end(GameEndReason.AllOpponentsLost, computer.getName(), null);
} }
} if (reason != null) {
game.setGameOver();
Singletons.getModel().getMatch().addGamePlayed(reason, game);
} }
final boolean isGameDone = humanWins || computerWins; return reason != null;
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);
}
return isGameDone;
} }
/** */ /** */
@@ -1015,7 +1005,7 @@ public class GameAction {
return; return;
} }
if (this.checkEndGameState()) { if (this.checkEndGameState(Singletons.getModel().getGameState())) {
// Clear Simultaneous triggers at the end of the game // Clear Simultaneous triggers at the end of the game
new ViewWinLose(); new ViewWinLose();
Singletons.getModel().getGameState().getStack().clearSimultaneousStack(); Singletons.getModel().getGameState().getStack().clearSimultaneousStack();
@@ -1031,9 +1021,6 @@ public class GameAction {
boolean checkAgain = false; boolean checkAgain = false;
AllZone.getHumanPlayer().setMaxHandSize(7);
AllZone.getComputerPlayer().setMaxHandSize(7);
this.checkStaticAbilities(); this.checkStaticAbilities();
final HashMap<String, Object> runParams = new HashMap<String, Object>(); final HashMap<String, Object> runParams = new HashMap<String, Object>();
@@ -1693,7 +1680,7 @@ public class GameAction {
originalCard.setXManaCostPaid(0); originalCard.setXManaCostPaid(0);
} }
if (PhaseHandler.getGameBegins() != 1 || sa.isTrigger()) { if (Singletons.getModel().getGameState() != null || sa.isTrigger()) {
return manaCost; return manaCost;
} }

View File

@@ -29,7 +29,6 @@ import forge.CardUtil;
import forge.Singletons; import forge.Singletons;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
import forge.card.spellability.Spell; import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellPermanent; import forge.card.spellability.SpellPermanent;

View File

@@ -64,7 +64,6 @@ public class ManaPool {
*/ */
public ManaPool(final Player player) { public ManaPool(final Player player) {
owner = player; owner = player;
owner.updateObservers();
clearPool(); clearPool();
ManaPool.MAP.put(Constant.Color.WHITE, 0); ManaPool.MAP.put(Constant.Color.WHITE, 0);
ManaPool.MAP.put(Constant.Color.BLUE, 1); ManaPool.MAP.put(Constant.Color.BLUE, 1);

View File

@@ -35,6 +35,7 @@ import forge.AllZone;
import forge.Singletons; import forge.Singletons;
import forge.control.KeyboardShortcuts.Shortcut; import forge.control.KeyboardShortcuts.Shortcut;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.deckeditor.VDeckEditorUI;
import forge.gui.framework.SOverflowUtil; import forge.gui.framework.SOverflowUtil;
@@ -49,6 +50,7 @@ import forge.properties.ForgeProps;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.QuestDataIO; import forge.quest.io.QuestDataIO;
import forge.util.Aggregates;
import forge.view.FView; import forge.view.FView;
/** /**
@@ -273,6 +275,20 @@ public enum FControl {
/** @return {@link forge.game.player.Player} */ /** @return {@link forge.game.player.Player} */
public Player getPlayer() { 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;
} }
} }

View File

@@ -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!
}
}

View File

@@ -21,6 +21,7 @@ import java.util.LinkedList;
import java.util.Stack; import java.util.Stack;
import forge.AllZone; import forge.AllZone;
import forge.Singletons;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.ComputerAIInput; import forge.game.player.ComputerAIInput;
@@ -198,7 +199,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
return this.input; 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 // Handle begin phase stuff, then start back from the top
handler.handleBeginPhase(); handler.handleBeginPhase();
return this.updateInput(); return this.updateInput();
@@ -215,7 +216,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
this.model.getGameState().getStack().freezeStack(); this.model.getGameState().getStack().freezeStack();
if (playerTurn.isHuman() && !handler.getAutoPass()) { if (playerTurn.isHuman() && !handler.getAutoPass()) {
AllZone.getCombat().initiatePossibleDefenders(AllZone.getComputerPlayer()); AllZone.getCombat().initiatePossibleDefenders(playerTurn.getOpponent());
return new InputAttack(); return new InputAttack();
} }
} else if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS) { } else if (phase == PhaseType.COMBAT_DECLARE_BLOCKERS) {

View File

@@ -30,8 +30,6 @@ import forge.GameActionUtil;
import forge.Singletons; import forge.Singletons;
import forge.card.abilityfactory.AbilityFactory; import forge.card.abilityfactory.AbilityFactory;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.GamePlayerRating;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseUtil; import forge.game.phase.PhaseUtil;
import forge.game.player.ComputerUtil; import forge.game.player.ComputerUtil;
import forge.game.player.Player; import forge.game.player.Player;
@@ -41,8 +39,6 @@ import forge.gui.framework.SDisplayUtil;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
import forge.gui.match.VMatchUI; import forge.gui.match.VMatchUI;
import forge.gui.match.views.VMessage; import forge.gui.match.views.VMessage;
import forge.quest.QuestController;
import forge.quest.bazaar.QuestItemType;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
/** /**
* <p> * <p>
@@ -56,7 +52,6 @@ public class InputMulligan extends Input {
/** Constant <code>serialVersionUID=-8112954303001155622L</code>. */ /** Constant <code>serialVersionUID=-8112954303001155622L</code>. */
private static final long 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; private static final int AI_MULLIGAN_THRESHOLD = 5;
/** {@inheritDoc} */ /** {@inheritDoc} */
@@ -67,7 +62,7 @@ public class InputMulligan extends Input {
VMatchUI.SINGLETON_INSTANCE.getBtnCancel().setText("Yes"); VMatchUI.SINGLETON_INSTANCE.getBtnCancel().setText("Yes");
final String str = 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. "); ? "You're going first. " : "The computer is going first. ");
CMatchUI.SINGLETON_INSTANCE.showMessage(str + "Do you want to Mulligan?"); CMatchUI.SINGLETON_INSTANCE.showMessage(str + "Do you want to Mulligan?");
} }
@@ -78,75 +73,40 @@ public class InputMulligan extends Input {
this.end(); 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<Card> 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} */ /** {@inheritDoc} */
@Override @Override
public final void selectButtonCancel() { public final void selectButtonCancel() {
final Player humanPlayer = AllZone.getHumanPlayer(); final Player humanPlayer = Singletons.getControl().getPlayer();
final GamePlayerRating humanRating = Singletons.getModel().getGameSummary().getPlayerRating(humanPlayer.getName());
final int newHand = this.doMulligan(humanPlayer, humanRating);
final QuestController quest = Singletons.getModel().getQuest(); final int newHand = humanPlayer.doMulligan();
if (quest.isLoaded() && quest.getAssets().hasItem(QuestItemType.SLEIGHT) && (humanRating.getMulliganCount() == 1)) {
AllZone.getHumanPlayer().drawCard();
humanRating.notifyOpeningHandSize(newHand + 1);
}
if (newHand == 0) { if (newHand == 0) {
this.end(); this.end();
} }
} // selectButtonOK() } // selectButtonOK()
/**
* <p>
* end.
* </p>
*/
final void end() { final void end() {
// Computer mulligan // Computer mulligan
final GameAction ga = Singletons.getModel().getGameAction();
final Player aiPlayer = AllZone.getComputerPlayer(); for (Player ai : Singletons.getModel().getGameState().getPlayers()) {
final GamePlayerRating aiRating = Singletons.getModel().getGameSummary().getPlayerRating(aiPlayer.getName()); if ( ai.isHuman() ) continue;
boolean aiTakesMulligan = true; boolean aiTakesMulligan = true;
// Computer mulligans if there are no cards with converted mana cost of // Computer mulligans if there are no cards with converted mana cost of
// 0 in its hand // 0 in its hand
while (aiTakesMulligan) { while (aiTakesMulligan) {
final List<Card> handList = aiPlayer.getCardsIn(ZoneType.Hand); final List<Card> handList = ai.getCardsIn(ZoneType.Hand);
final boolean hasLittleCmc0Cards = CardLists.getValidCards(handList, "Card.cmcEQ0", aiPlayer, null).size() < 2; final boolean hasLittleCmc0Cards = CardLists.getValidCards(handList, "Card.cmcEQ0", ai, null).size() < 2;
aiTakesMulligan = (handList.size() > InputMulligan.AI_MULLIGAN_THRESHOLD) && hasLittleCmc0Cards; aiTakesMulligan = (handList.size() > InputMulligan.AI_MULLIGAN_THRESHOLD) && hasLittleCmc0Cards;
if (aiTakesMulligan) { if (aiTakesMulligan) {
this.doMulligan(aiPlayer, aiRating); ai.doMulligan();
}
} }
} }
@@ -154,6 +114,7 @@ public class InputMulligan extends Input {
ButtonUtil.reset(); ButtonUtil.reset();
final AbilityFactory af = new AbilityFactory(); final AbilityFactory af = new AbilityFactory();
final GameAction ga = Singletons.getModel().getGameAction();
for (Player p : Singletons.getModel().getGameState().getPlayers()) { for (Player p : Singletons.getModel().getGameState().getPlayers()) {
final List<Card> openingHand = p.getCardsIn(ZoneType.Hand); final List<Card> openingHand = p.getCardsIn(ZoneType.Hand);
@@ -210,7 +171,7 @@ public class InputMulligan extends Input {
//ga.checkStateEffects(); //ga.checkStateEffects();
ga.checkStateEffects(); ga.checkStateEffects();
PhaseHandler.setGameBegins(1);
AllZone.getGameLog().add("Turn", AllZone.getGameLog().add("Turn",
"Turn " + Singletons.getModel().getGameState().getPhaseHandler().getTurn() "Turn " + Singletons.getModel().getGameState().getPhaseHandler().getTurn()
+ " (" + Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn() + ")", + " (" + Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn() + ")",

View File

@@ -86,7 +86,7 @@ public class InputPassPriority extends Input implements java.io.Serializable {
@Override @Override
public final void selectCard(final Card card, final PlayerZone zone) { public final void selectCard(final Card card, final PlayerZone zone) {
if (Singletons.getModel().getGameAction().playCard(card)) { if (Singletons.getModel().getGameAction().playCard(card)) {
Singletons.getModel().getGameState().getPhaseHandler().setPriority(AllZone.getHumanPlayer()); Singletons.getModel().getGameState().getPhaseHandler().setPriority(Singletons.getControl().getPlayer());
} }
else { else {
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE); SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);

View File

@@ -23,7 +23,6 @@ import forge.Singletons;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.phase.PhaseHandler;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -76,7 +75,7 @@ public class InputPayManaCost extends InputMana {
this.spell = sa; this.spell = sa;
if (PhaseHandler.getGameBegins() == 1) { if (Singletons.getModel().getGameState() != null) {
if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) { if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) {
if (this.spell.getAfterPayMana() != null) { if (this.spell.getAfterPayMana() != null) {
this.stopSetNext(this.spell.getAfterPayMana()); this.stopSetNext(this.spell.getAfterPayMana());
@@ -121,7 +120,7 @@ public class InputPayManaCost extends InputMana {
this.spell = sa; this.spell = sa;
if (PhaseHandler.getGameBegins() == 1) { if (Singletons.getModel().getGameState() != null ) {
if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) { if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) {
if (this.spell.getAfterPayMana() != null) { if (this.spell.getAfterPayMana() != null) {
this.stopSetNext(this.spell.getAfterPayMana()); this.stopSetNext(this.spell.getAfterPayMana());
@@ -266,8 +265,9 @@ public class InputPayManaCost extends InputMana {
} }
this.resetManaCost(); this.resetManaCost();
AllZone.getHumanPlayer().getManaPool().refundManaPaid(this.spell, true); Player human = Singletons.getControl().getPlayer();
AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); // DO human.getManaPool().refundManaPaid(this.spell, true);
human.getZone(ZoneType.Battlefield).updateObservers(); // DO
this.stop(); this.stop();
} }

View File

@@ -17,7 +17,6 @@
*/ */
package forge.control.input; package forge.control.input;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
@@ -202,7 +201,7 @@ public class InputPayManaCostAbility extends InputMana {
public final void selectButtonCancel() { public final void selectButtonCancel() {
this.unpaidCommand.execute(); this.unpaidCommand.execute();
this.resetManaCost(); this.resetManaCost();
AllZone.getHumanPlayer().getManaPool().refundManaPaid(this.fakeAbility, true); Singletons.getControl().getPlayer().getManaPool().refundManaPaid(this.fakeAbility, true);
this.stop(); this.stop();
} }

View File

@@ -37,7 +37,6 @@ import forge.card.mana.ManaPool;
import forge.card.spellability.AbilityMana; import forge.card.spellability.AbilityMana;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.game.phase.PhaseHandler;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -418,7 +417,7 @@ public class InputPayManaCostUtil {
public void selectButtonCancel() { public void selectButtonCancel() {
this.stop(); this.stop();
payment.cancelCost(); payment.cancelCost();
AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); Singletons.getControl().getPlayer().getZone(ZoneType.Battlefield).updateObservers();
} }
@Override @Override
@@ -470,7 +469,7 @@ public class InputPayManaCostUtil {
final int manaToAdd) { final int manaToAdd) {
final ManaCost manaCost; final ManaCost manaCost;
if (PhaseHandler.getGameBegins() == 1) { if (Singletons.getModel().getGameState() != null ) {
final String mana = costMana.getManaToPay(); final String mana = costMana.getManaToPay();
manaCost = new ManaCost(mana); manaCost = new ManaCost(mana);
manaCost.increaseColorlessMana(manaToAdd); manaCost.increaseColorlessMana(manaToAdd);
@@ -574,7 +573,7 @@ public class InputPayManaCostUtil {
this.stop(); this.stop();
this.resetManaCost(); this.resetManaCost();
payment.cancelCost(); payment.cancelCost();
AllZone.getHumanPlayer().getZone(ZoneType.Battlefield).updateObservers(); Singletons.getControl().getPlayer().getZone(ZoneType.Battlefield).updateObservers();
} }
@Override @Override

View File

@@ -19,7 +19,6 @@ package forge.control.input;
import java.util.List; import java.util.List;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
@@ -77,7 +76,7 @@ public class InputPayReturnCost extends Input {
this.ability = sa; this.ability = sa;
this.returnCost = cost; 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(); String amountString = cost.getAmount();
this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
: CardFactoryUtil.xCount(source, source.getSVar(amountString)); : CardFactoryUtil.xCount(source, source.getSVar(amountString));

View File

@@ -19,7 +19,6 @@ package forge.control.input;
import java.util.List; import java.util.List;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
@@ -28,6 +27,7 @@ import forge.Singletons;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.CostSacrifice; import forge.card.cost.CostSacrifice;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
@@ -77,7 +77,8 @@ public class InputPaySacCost extends Input {
this.ability = sa; this.ability = sa;
this.sacCost = cost; 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(); String amountString = cost.getAmount();
this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString) this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
: CardFactoryUtil.xCount(source, source.getSVar(amountString)); : CardFactoryUtil.xCount(source, source.getSVar(amountString));

View File

@@ -21,10 +21,6 @@ package forge.game;
* The Enum GameLossReason. * The Enum GameLossReason.
*/ */
public 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. */ /** The Conceded. */
Conceded, // rule 104.3a Conceded, // rule 104.3a
/** The Life reached zero. */ /** The Life reached zero. */
@@ -36,7 +32,9 @@ public enum GameLossReason {
// 104.3e and others // 104.3e and others
/** The Spell effect. */ /** The Spell effect. */
SpellEffect SpellEffect,
OpponentWon
/* /*
* DoorToNothingness, // Door To Nothingness's ability activated * DoorToNothingness, // Door To Nothingness's ability activated

View File

@@ -19,21 +19,12 @@ import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates; import forge.CardPredicates;
import forge.CardUtil; import forge.CardUtil;
import forge.Constant.Preferences;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.deck.Deck;
import forge.control.input.InputMulligan;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; 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.match.views.VAntes;
import forge.gui.toolbox.FLabel;
import forge.item.CardPrinted; import forge.item.CardPrinted;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -44,86 +35,22 @@ import forge.util.MyRandom;
* All of these methods can and should be static. * All of these methods can and should be static.
*/ */
public class GameNew { public class GameNew {
/** private static void prepareSingleLibrary(final Player player, final Deck deck, final Map<Player, List<String>> removedAnteCards, final List<String> rAICards) {
* Constructor for new game allowing card lists to be put into play
* immediately, and life totals to be adjusted, for computer and human.
*
* 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();
Singletons.getModel().getPreferences().actuateMatchPreferences();
Card.resetUniqueNumber();
for( PlayerStartsGame p : players ) {
final Player player = p.getPlayer();
player.setStartingLife(p.initialLives);
// 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) {
c.addController(player);
c.setOwner(player);
bf.add(c, false);
c.setSickness(true);
c.setStartsGameInPlay(true);
c.refreshUniqueNumber();
}
}
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(); final Random generator = MyRandom.getRandom();
boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE); boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE);
final Map<Player, List<String>> removedAnteCards = new HashMap<Player, List<String>>(); final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL)
final List<String> rAICards = new ArrayList<String>(); && Singletons.getModel().getMatch().getGameType() == GameType.Constructed;
// Create Card libraries out of decks (CardPrinted)
for( PlayerStartsGame p : players ) PlayerZone library = player.getZone(ZoneType.Library);
{ for (final Entry<CardPrinted, Integer> stackOfCards : deck.getMain()) {
PlayerZone library = p.getPlayer().getZone(ZoneType.Library);
for (final Entry<CardPrinted, Integer> stackOfCards : p.getDeck().getMain()) {
final CardPrinted cardPrinted = stackOfCards.getKey(); final CardPrinted cardPrinted = stackOfCards.getKey();
for (int i = 0; i < stackOfCards.getValue(); i++) { for (int i = 0; i < stackOfCards.getValue(); i++) {
final Card card = cardPrinted.toForgeCard(p.getPlayer()); final Card card = cardPrinted.toForgeCard(player);
// apply random pictures for cards // apply random pictures for cards
if ( p.getPlayer().isComputer() ) { if ( player.isComputer() ) {
final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount(); final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount();
if (cntVariants > 1) { if (cntVariants > 1) {
card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1); card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1);
@@ -138,23 +65,78 @@ public class GameNew {
} }
if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) { if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) {
if(!removedAnteCards.containsKey(p.getPlayer())) if(!removedAnteCards.containsKey(player))
removedAnteCards.put(p.getPlayer(), new ArrayList<String>()); removedAnteCards.put(player, new ArrayList<String>());
removedAnteCards.get(p.getPlayer()).add(card.getName()); removedAnteCards.get(player).add(card.getName());
} else { } else {
library.add(card); library.add(card);
} }
// mark card as difficult for AI to play // mark card as difficult for AI to play
if ( p.getPlayer().isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) { if ( player.isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) {
rAICards.add(card.getName()); rAICards.add(card.getName());
// get card picture so that it is in the image cache // get card picture so that it is in the image cache
// ImageCache.getImage(card); // 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<Card> 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.
*
* 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 Map<Player, PlayerStartConditions> playersConditions) {
AllZone.getInputControl().clearInput();
AllZone.getColorChanger().reset();
Card.resetUniqueNumber();
// need this code here, otherwise observables fail
forge.card.trigger.Trigger.resetIDs();
AllZone.getTriggerHandler().clearTriggerSettings();
AllZone.getTriggerHandler().clearDelayedTrigger();
// friendliness
final Map<Player, List<String>> removedAnteCards = new HashMap<Player, List<String>>();
final List<String> rAICards = new ArrayList<String>();
for( Entry<Player, PlayerStartConditions> p : playersConditions.entrySet() ) {
final Player player = p.getKey();
player.setStartingLife(p.getValue().getStartingLife());
// what if I call it for AI player?
PlayerZone bf = player.getZone(ZoneType.Battlefield);
if (p.getValue().getCardsOnTable() != null) {
for (final Card c : p.getValue().getCardsOnTable()) {
c.addController(player);
c.setOwner(player);
bf.add(c, false);
c.setSickness(true);
c.setStartsGameInPlay(true);
c.refreshUniqueNumber();
}
}
prepareSingleLibrary(player, p.getValue().getDeck(), removedAnteCards, rAICards);
player.updateObservers();
bf.updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
}
if (rAICards.size() > 0) { if (rAICards.size() > 0) {
String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards); String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards);
JOptionPane.showMessageDialog(null, message, "", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(null, message, "", JOptionPane.INFORMATION_MESSAGE);
@@ -168,33 +150,17 @@ public class GameNew {
JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE);
} }
GameNew.actuateGame();
// 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()
// 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<Card> 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 // Deciding which cards go to ante
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE)) { if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE)) {
@@ -217,17 +183,16 @@ public class GameNew {
// Only cut/coin toss if it's the first game of the match // 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(); 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 { } 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 // Draw 7 cards
for (final Player p : Singletons.getModel().getGameState().getPlayers()) for (final Player p : Singletons.getModel().getGameState().getPlayers())
{ {
@@ -235,9 +200,6 @@ public class GameNew {
p.drawCard(); p.drawCard();
} }
} }
CMatchUI.SINGLETON_INSTANCE.setCard(AllZone.getHumanPlayer().getCardsIn(ZoneType.Hand).get(0));
AllZone.getInputControl().setInput(new InputMulligan());
} // newGame() } // newGame()
private static String buildFourColumnList(String firstLine, List<String> cAnteRemoved ) { private static String buildFourColumnList(String firstLine, List<String> cAnteRemoved ) {
@@ -254,52 +216,6 @@ public class GameNew {
return sb.toString(); 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<VField> 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 // this is where the computer cheats
// changes AllZone.getComputerPlayer().getZone(Zone.Library) // changes AllZone.getComputerPlayer().getZone(Zone.Library)
@@ -371,48 +287,34 @@ public class GameNew {
computerDie = MyRandom.getRandom().nextInt(20); computerDie = MyRandom.getRandom().nextInt(20);
} }
if (playerDie > computerDie) { List<Player> allPlayers = Singletons.getModel().getGameState().getPlayers();
humanPlayOrDraw(dieRollMessage(playerDie, computerDie)); setPlayersFirstTurn(allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size())));
} }
else {
computerPlayOrDraw(dieRollMessage(playerDie, computerDie)); 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() } // seeWhoPlaysFirstDice()
private static boolean humanPlayOrDraw(String message) {
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) {
final Object[] possibleValues = { "Play", "Draw" }; final Object[] possibleValues = { "Play", "Draw" };
final Object playDraw = JOptionPane.showOptionDialog(null, message + "\n\nWould you like to play or 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, "Play or Draw?", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
possibleValues, possibleValues[0]); possibleValues, possibleValues[0]);
if (playDraw.equals(1)) { return !playDraw.equals(1);
computerStartsGame();
}
} }
private static void computerPlayOrDraw(String message) { private static void computerPlayOrDraw(String message) {
JOptionPane.showMessageDialog(null, message + "\nComputer Going First", JOptionPane.showMessageDialog(null, message + "\nComputer Going First",
"Play or Draw?", JOptionPane.INFORMATION_MESSAGE); "Play or Draw?", JOptionPane.INFORMATION_MESSAGE);
computerStartsGame();
} }
} }

View File

@@ -19,7 +19,13 @@ package forge.game;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerStatistics;
/** /**
* <p> * <p>
@@ -27,16 +33,14 @@ import java.util.Map;
* </p> * </p>
* *
* @author Forge * @author Forge
* @version $Id$ * @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 // This class might be divided in two parts: the very summary (immutable with
// only getters) and // only getters) and
// GameObserver class - who should be notified of any considerable ingame event // GameObserver class - who should be notified of any considerable ingame event
public final class GameSummary { public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStatistics>> {
/** The player winner. */
private String playerWinner = "Nobody";
/** The player got first turn. */ /** The player got first turn. */
// private String playerGotFirstTurn = "Nobody"; // private String playerGotFirstTurn = "Nobody";
@@ -44,14 +48,10 @@ public final class GameSummary {
/** The last turn number. */ /** The last turn number. */
private int lastTurnNumber = 0; private int lastTurnNumber = 0;
/** The win condition. */
private GameEndReason winCondition;
/** The spell effect win. */
private String spellEffectWin;
/** The player rating. */ /** The player rating. */
private final Map<String, GamePlayerRating> playerRating = new HashMap<String, GamePlayerRating>(); private final Map<LobbyPlayer, PlayerStatistics> playerRating = new HashMap<LobbyPlayer, PlayerStatistics>(4);
private GameEndReason winCondition;
/** /**
* Instantiates a new game summary. * Instantiates a new game summary.
@@ -59,31 +59,17 @@ public final class GameSummary {
* @param names * @param names
* the names * the names
*/ */
public GameSummary(final String... names) { public GameOutcome(GameEndReason reason, final Player... names) {
this(Arrays.asList(names)); this(reason, Arrays.asList(names));
} }
public GameSummary(final Iterable<String> list) { public GameOutcome(GameEndReason reason, final Iterable<Player> list) {
for (final String n : list) { winCondition = reason;
this.playerRating.put(n, new GamePlayerRating()); for (final Player n : list) {
this.playerRating.put(n.getLobbyPlayer(), n.getStats());
} }
} }
/**
* 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. * Checks if is draw.
@@ -91,7 +77,12 @@ public final class GameSummary {
* @return true, if is draw * @return true, if is draw
*/ */
public boolean isDraw() { public boolean isDraw() {
return null == this.playerWinner; for( PlayerStatistics pv : playerRating.values())
{
if ( pv.getOutcome().hasWon() )
return false;
}
return true;
} }
/** /**
@@ -101,8 +92,9 @@ public final class GameSummary {
* the name * the name
* @return true, if is winner * @return true, if is winner
*/ */
public boolean isWinner(final String name) { public boolean isWinner(final LobbyPlayer who) {
return (name != null) && name.equals(this.playerWinner); PlayerStatistics stats = playerRating.get(who);
return stats.getOutcome().hasWon();
} }
/** /**
@@ -110,8 +102,13 @@ public final class GameSummary {
* *
* @return the winner * @return the winner
*/ */
public String getWinner() { public LobbyPlayer getWinner() {
return this.playerWinner; for( Entry<LobbyPlayer, PlayerStatistics> ps : playerRating.entrySet())
{
if ( ps.getValue().getOutcome().hasWon() )
return ps.getKey();
}
return null;
} }
/** /**
@@ -130,7 +127,7 @@ public final class GameSummary {
* the name * the name
* @return the player rating * @return the player rating
*/ */
public GamePlayerRating getPlayerRating(final String name) { public PlayerStatistics getStatistics(final LobbyPlayer name) {
return this.playerRating.get(name); return this.playerRating.get(name);
} }
@@ -152,20 +149,26 @@ public final class GameSummary {
* this.playerGotFirstTurn = playerName; } * this.playerGotFirstTurn = playerName; }
*/ */
/**
* Notify next turn.
*/
public void notifyNextTurn() {
this.lastTurnNumber++;
}
/** /**
* Gets the win spell effect. * Gets the win spell effect.
* *
* @return the win spell effect * @return the win spell effect
*/ */
public String getWinSpellEffect() { public String getWinSpellEffect() {
return this.spellEffectWin; 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<Entry<LobbyPlayer, PlayerStatistics>> iterator() {
return playerRating.entrySet().iterator();
} }
} }

View File

@@ -32,8 +32,7 @@ import forge.game.phase.EndOfTurn;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.Untap; import forge.game.phase.Untap;
import forge.game.phase.Upkeep; import forge.game.phase.Upkeep;
import forge.game.player.AIPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.HumanPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.game.zone.MagicStack; import forge.game.zone.MagicStack;
@@ -51,14 +50,13 @@ public class GameState {
/** The Constant AI_PLAYER_NAME. */ /** The Constant AI_PLAYER_NAME. */
public static final String AI_PLAYER_NAME = "Computer"; public static final String AI_PLAYER_NAME = "Computer";
private final List<Player> players = new ArrayList<Player>();
private final List<Player> roPlayers; private final List<Player> roPlayers;
private final Cleanup cleanup = new Cleanup(); private final Cleanup cleanup = new Cleanup();
private final EndOfTurn endOfTurn = new EndOfTurn(); private final EndOfTurn endOfTurn = new EndOfTurn();
private final EndOfCombat endOfCombat = new EndOfCombat(); private final EndOfCombat endOfCombat = new EndOfCombat();
private final Untap untap = new Untap(); private final Untap untap = new Untap();
private final Upkeep upkeep = new Upkeep(); 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 MagicStack stack = new MagicStack();
private final StaticEffects staticEffects = new StaticEffects(); private final StaticEffects staticEffects = new StaticEffects();
private final TriggerHandler triggerHandler = new TriggerHandler(); private final TriggerHandler triggerHandler = new TriggerHandler();
@@ -70,15 +68,17 @@ public class GameState {
private final PlayerZone stackZone = new PlayerZone(ZoneType.Stack, null); private final PlayerZone stackZone = new PlayerZone(ZoneType.Stack, null);
private long timestamp = 0; private long timestamp = 0;
private GameSummary gameSummary; private int nTurn = 0;
/** /**
* Constructor. * Constructor.
* @param players2
*/ */
public GameState() { /* no more zones to map here */ public GameState(Iterable<LobbyPlayer> players2) { /* no more zones to map here */
players.add(new HumanPlayer(GameState.HUMAN_PLAYER_NAME)); List<Player> players = new ArrayList<Player>();
players.add(new AIPlayer(GameState.AI_PLAYER_NAME)); for(LobbyPlayer p : players2) {
players.add(p.getIngamePlayer());
}
roPlayers = Collections.unmodifiableList(players); roPlayers = Collections.unmodifiableList(players);
} }
@@ -238,23 +238,6 @@ public class GameState {
this.timestamp = timestamp0; 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 * @return the replacementHandler
@@ -273,8 +256,25 @@ public class GameState {
/** /**
* @param go the gameOver to set * @param go the gameOver to set
*/ */
public void setGameOver(boolean go) { public void setGameOver() {
this.gameOver = go; 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++;
}
} }

View File

@@ -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<LobbyPlayer, PlayerStartConditions> players = new HashMap<LobbyPlayer, PlayerStartConditions>();
private GameType gameType = GameType.Constructed;
private int gamesPerMatch = 3;
private int gamesToWinMatch = 2;
private GameState currentGame = null;
private final List<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>();
private final List<GameOutcome> gamesPlayedRo;
public MatchController() {
gamesPlayedRo = Collections.unmodifiableList(gamesPlayed);
}
/**
* Gets the games played.
*
* @return the games played
*/
public final List<GameOutcome> 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<Player, PlayerStartConditions> startConditions = new HashMap<Player, PlayerStartConditions>();
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<LobbyPlayer, PlayerStartConditions> 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();
}
}

View File

@@ -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<LobbyPlayer, PlayerStartConditions> players = new HashMap<LobbyPlayer, PlayerStartConditions>();
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<LobbyPlayer, PlayerStartConditions> getPlayerMap()
{
return players;
}
}

View File

@@ -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<Card> cardsOnTable = null;
public PlayerStartConditions( Deck deck0 ) {
deck = deck0;
}
public final Deck getDeck() {
return deck;
}
public final int getStartingLife() {
return startingLife;
}
public final List<Card> getCardsOnTable() {
return cardsOnTable;
}
public final void setStartingLife(int startingLife) {
this.startingLife = startingLife;
}
public final void setCardsOnTable(List<Card> cardsOnTable) {
this.cardsOnTable = cardsOnTable;
}
}

View File

@@ -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 <Card>
*
*/
public class PlayerStartsGame {
private final Player player;
private final Deck deck;
public int initialLives = 20;
public List<Card> cardsOnBattlefield = null;
public PlayerStartsGame(Player who, Deck cards) {
player = who;
deck = cards;
}
public Player getPlayer() {
return player;
}
public Deck getDeck() {
return deck;
}
}

View File

@@ -19,16 +19,17 @@ package forge.game.limited;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import java.util.List; import java.util.List;
import forge.AllZone;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameNew;
import forge.game.GameType; 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.SOverlayUtils;
import forge.gui.match.CMatchUI;
/** /**
* <p> * <p>
@@ -158,10 +159,15 @@ public class GauntletMini {
@Override @Override
public Object doInBackground() { public Object doInBackground() {
CMatchUI.SINGLETON_INSTANCE.initMatch(null);
Singletons.getModel().getMatchState().setGameType(gauntletType); MatchStartHelper starter = new MatchStartHelper();
GameNew.newGame( new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck), Lobby lobby = Singletons.getControl().getLobby();
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDecks.get(currentRound))); 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; return null;
} }

View File

@@ -382,7 +382,7 @@ public class CombatUtil {
*/ */
public static boolean finishedMandatoryBlocks(final Combat combat) { public static boolean finishedMandatoryBlocks(final Combat combat) {
final List<Card> blockers = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); final List<Card> blockers = AllZoneUtil.getCreaturesInPlay(Singletons.getControl().getPlayer());
final List<Card> attackers = combat.getAttackerList(); final List<Card> attackers = combat.getAttackerList();
// if a creature does not block but should, return false // if a creature does not block but should, return false

View File

@@ -19,7 +19,6 @@ package forge.game.phase;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Observer;
import java.util.Stack; import java.util.Stack;
import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log;
@@ -53,27 +52,39 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */ /** Constant <code>serialVersionUID=5207222278370963197L</code>. */
private static final long serialVersionUID = 5207222278370963197L; private static final long serialVersionUID = 5207222278370963197L;
private int phaseIndex; private int phaseIndex = 0;
private int turn; private int turn = 1;
// Please use getX, setX, and incrementX methods instead of directly
// accessing the following:
/** Constant <code>GameBegins=0</code>. */
private static int gameBegins = 0;
private final Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>(); private final Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
private int extraCombats; private int extraCombats = 0;
private int nCombatsThisTurn; private int nCombatsThisTurn = 0;
private boolean bPreventCombatDamageThisTurn; 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 PhaseType skipToPhase = PhaseType.CLEANUP;
private boolean autoPass = false; 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;
/** /**
* <p> * <p>
* isPlayerTurn. * isPlayerTurn.
@@ -112,8 +123,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
// priority player // priority player
private Player pPlayerPriority = AllZone.getHumanPlayer();
/** /**
* <p> * <p>
* getPriorityPlayer. * getPriorityPlayer.
@@ -137,8 +146,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.pPlayerPriority = p; this.pPlayerPriority = p;
} }
private Player pFirstPriority = AllZone.getHumanPlayer();
/** /**
* <p> * <p>
* getFirstPriority. * getFirstPriority.
@@ -188,8 +195,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.setPriority(this.playerTurn); this.setPriority(this.playerTurn);
} }
private boolean bPhaseEffects = true;
/** /**
* <p> * <p>
* doPhaseEffects. * doPhaseEffects.
@@ -213,8 +218,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bPhaseEffects = b; this.bPhaseEffects = b;
} }
private boolean bSkipPhase = true;
/** /**
* <p> * <p>
* doSkipPhase. * doSkipPhase.
@@ -238,8 +241,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bSkipPhase = b; this.bSkipPhase = b;
} }
private boolean bCombat = false;
/** /**
* <p> * <p>
* inCombat. * inCombat.
@@ -263,8 +264,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bCombat = b; this.bCombat = b;
} }
private boolean bRepeat = false;
/** /**
* <p> * <p>
* repeatPhase. * repeatPhase.
@@ -274,38 +273,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bRepeat = true; this.bRepeat = true;
} }
/**
* <p>
* Constructor for PhaseHandler.
* </p>
*/
public PhaseHandler() {
this.reset();
}
/**
* <p>
* reset.
* </p>
*/
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();
}
/** /**
* <p> * <p>
* handleBeginPhase. * 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;
/** /**
* <p> * <p>
* Setter for the field <code>needToNextPhase</code>. * Setter for the field <code>needToNextPhase</code>.
@@ -934,11 +892,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
return this.needToNextPhase; 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;
/** /**
* <p> * <p>
* isNeedToNextPhaseInit. * isNeedToNextPhaseInit.
@@ -998,31 +951,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
return now.isPlayerTurn(player) && now.getPhase().isMain() && onlyThis; return now.isPlayerTurn(player) && now.getPhase().isMain() && onlyThis;
} }
/**
* <p>
* setGameBegins.
* </p>
*
* @param gameBegins
* a int.
*/
public static void setGameBegins(final int gameBegins) {
PhaseHandler.gameBegins = gameBegins;
}
/**
* <p>
* getGameBegins.
* </p>
*
* @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 // this is a hack for the setup game state mode, do not use outside of
// devSetupGameState code // devSetupGameState code
// as it avoids calling any of the phase effects that may be necessary in a // as it avoids calling any of the phase effects that may be necessary in a

View File

@@ -87,8 +87,8 @@ public class PhaseUtil {
final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler(); final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler();
final Player turn = ph.getPlayerTurn(); final Player turn = ph.getPlayerTurn();
Singletons.getModel().getGameSummary().notifyNextTurn(); Singletons.getModel().getGameState().notifyNextTurn();
CMessage.SINGLETON_INSTANCE.updateGameInfo(); CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch());
AllZone.getCombat().reset(); AllZone.getCombat().reset();
AllZone.getCombat().setAttackingPlayer(turn); AllZone.getCombat().setAttackingPlayer(turn);

View File

@@ -50,24 +50,8 @@ public class AIPlayer extends Player {
* @param myName * @param myName
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
public AIPlayer(final String myName) { public AIPlayer(final LobbyPlayer player) {
this(myName, 20, 0); super(player);
}
/**
* <p>
* Constructor for AIPlayer.
* </p>
*
* @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);
} }

View File

@@ -29,6 +29,8 @@ import forge.control.input.Input;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
import forge.quest.QuestController;
import forge.quest.bazaar.QuestItemType;
/** /**
* <p> * <p>
@@ -48,24 +50,8 @@ public class HumanPlayer extends Player {
* @param myName * @param myName
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
public HumanPlayer(final String myName) { public HumanPlayer(final LobbyPlayer player) {
this(myName, 20, 0); super(player);
}
/**
* <p>
* Constructor for HumanPlayer.
* </p>
*
* @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);
} }
// ////////////// // //////////////
@@ -222,4 +208,15 @@ public class HumanPlayer extends Player {
return PlayerType.HUMAN; 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 } // end HumanPlayer class

View File

@@ -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;
}
}

View File

@@ -51,7 +51,6 @@ import forge.card.replacement.ReplacementResult;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.staticability.StaticAbility; import forge.card.staticability.StaticAbility;
import forge.card.trigger.TriggerType; import forge.card.trigger.TriggerType;
import forge.deck.Deck;
import forge.game.GameLossReason; import forge.game.GameLossReason;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
@@ -71,13 +70,13 @@ import forge.util.MyRandom;
*/ */
public abstract class Player extends GameEntity implements Comparable<Player> { public abstract class Player extends GameEntity implements Comparable<Player> {
/** The poison counters. */ /** The poison counters. */
private int poisonCounters; private int poisonCounters = 0;
/** The life. */ /** The life. */
private int life; private int life = 20;
/** The life this player started the game with. */ /** The life this player started the game with. */
private int startingLife; private int startingLife = 20;
/** The assigned damage. */ /** The assigned damage. */
private final Map<Card, Integer> assignedDamage = new HashMap<Card, Integer>(); private final Map<Card, Integer> assignedDamage = new HashMap<Card, Integer>();
@@ -88,24 +87,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
/** The num power surge lands. */ /** The num power surge lands. */
private int numPowerSurgeLands; 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. */ /** The skip next untap. */
private boolean skipNextUntap = false; private boolean skipNextUntap = false;
@@ -122,7 +103,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
private int maxHandSize = 7; private int maxHandSize = 7;
/** The last drawn card. */ /** The last drawn card. */
private Card lastDrawnCard; private Card lastDrawnCard = null;
/** The num drawn this turn. */ /** The num drawn this turn. */
private int numDrawnThisTurn = 0; private int numDrawnThisTurn = 0;
@@ -134,7 +115,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
private ArrayList<String> keywords = new ArrayList<String>(); private ArrayList<String> keywords = new ArrayList<String>();
/** The mana pool. */ /** The mana pool. */
private ManaPool manaPool = null; private ManaPool manaPool = new ManaPool(this);
/** The must attack entity. */ /** The must attack entity. */
private Object mustAttackEntity = null; private Object mustAttackEntity = null;
@@ -148,24 +129,19 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
/** The zones. */ /** The zones. */
private final Map<ZoneType, PlayerZone> zones = new EnumMap<ZoneType, PlayerZone>(ZoneType.class); private final Map<ZoneType, PlayerZone> zones = new EnumMap<ZoneType, PlayerZone>(ZoneType.class);
private PlayerStatistics stats = new PlayerStatistics();
/** The Constant ALL_ZONES. */ /** The Constant ALL_ZONES. */
public static final List<ZoneType> ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield, public static final List<ZoneType> 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;
/**
* <p> private LobbyPlayer lobbyPlayer;
* Constructor for Player.
* </p> public final PlayerOutcome getOutcome() {
* return stats.getOutcome();
* @param myName
* a {@link java.lang.String} object.
*/
public Player(final String myName) {
this(myName, 20, 0);
} }
/** /**
@@ -180,48 +156,19 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @param myPoisonCounters * @param myPoisonCounters
* a int. * 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) { 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); : new PlayerZone(z, this);
this.zones.put(z, toPut); this.zones.put(z, toPut);
} }
this.setName(lobbyPlayer.getName());
this.reset();
this.setName(myName);
this.life = myLife;
this.poisonCounters = myPoisonCounters;
} }
/** public final PlayerStatistics getStats() {
* <p> return stats;
* reset.
* </p>
*/
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<Card>();
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<String>();
this.keywords.clear();
this.manaPool = new ManaPool(this);
this.updateObservers();
} }
/** /**
@@ -1267,6 +1214,32 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
return drawn; 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<Card> 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;
}
/** /**
* <p> * <p>
* doDraw. * doDraw.
@@ -1307,7 +1280,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
} }
} }
if (PhaseHandler.getGameBegins() == 1) { if (Singletons.getModel().getGameState() != null) {
this.setLastDrawnCard(c); this.setLastDrawnCard(c);
c.setDrawnThisTurn(true); c.setDrawnThisTurn(true);
this.numDrawnThisTurn++; this.numDrawnThisTurn++;
@@ -1441,7 +1414,9 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return the all cards * @return the all cards
*/ */
public final List<Card> getAllCards() { public final List<Card> getAllCards() {
return this.getCardsIn(Player.ALL_ZONES); List<Card> 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<Player> {
* @return a int. * @return a int.
*/ */
public final int getTurn() { public final int getTurn() {
return this.nTurns; return this.stats.getTurnsPlayed();
} }
/** /**
@@ -2044,7 +2019,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* </p> * </p>
*/ */
public final void incrementTurn() { public final void incrementTurn() {
this.nTurns++; this.stats.nextTurn();
} }
/** /**
@@ -2116,48 +2091,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
// Game win/loss // Game win/loss
/**
* <p>
* Getter for the field <code>altWin</code>.
* </p>
*
* @return a boolean.
*/
public final boolean getAltWin() {
return this.altWin;
}
/**
* <p>
* Getter for the field <code>winCondition</code>.
* </p>
*
* @return a {@link java.lang.String} object.
*/
public final String getWinConditionSource() {
return this.altWinSourceName;
}
/**
* <p>
* Getter for the field <code>loseCondition</code>.
* </p>
*
* @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;
}
/** /**
* <p> * <p>
* altWinConditionMet. * altWinConditionMet.
@@ -2171,8 +2104,8 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
System.out.println("Tried to win, but currently can't."); System.out.println("Tried to win, but currently can't.");
return; return;
} }
this.altWin = true; this.setOutcome(PlayerOutcome.altWin(sourceName));
this.altWinSourceName = sourceName;
} }
/** /**
@@ -2187,6 +2120,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return a boolean. * @return a boolean.
*/ */
public final boolean loseConditionMet(final GameLossReason state, final String spellName) { public final boolean loseConditionMet(final GameLossReason state, final String spellName) {
if ( state != GameLossReason.OpponentWon ) {
if (this.cantLose()) { if (this.cantLose()) {
System.out.println("Tried to lose, but currently can't."); System.out.println("Tried to lose, but currently can't.");
return false; return false;
@@ -2200,9 +2134,9 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) { if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) {
return false; return false;
} }
}
this.lossState = state; setOutcome(PlayerOutcome.loss(state, spellName));
this.loseConditionSpell = spellName;
return true; return true;
} }
@@ -2210,8 +2144,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* Concede. * Concede.
*/ */
public final void concede() { // No cantLose checks - just lose public final void concede() { // No cantLose checks - just lose
this.lossState = GameLossReason.Conceded; setOutcome(PlayerOutcome.concede());
this.loseConditionSpell = null;
} }
/** /**
@@ -2222,7 +2155,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return a boolean. * @return a boolean.
*/ */
public final boolean cantLose() { public final boolean cantLose() {
if (this.lossState == GameLossReason.Conceded) { if (this.getOutcome() != null && this.getOutcome().lossState == GameLossReason.Conceded) {
return false; return false;
} }
@@ -2258,11 +2191,10 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* *
* @return a boolean. * @return a boolean.
*/ */
public final boolean hasLost() { public final boolean checkLoseCondition() {
if (this.lossState != GameLossReason.DidNotLoseYet) { if ( this.getOutcome() != null )
return this.loseConditionMet(this.lossState, null); return this.getOutcome().lossState != null;
}
if (this.poisonCounters >= 10) { if (this.poisonCounters >= 10) {
return this.loseConditionMet(GameLossReason.Poisoned, null); return this.loseConditionMet(GameLossReason.Poisoned, null);
@@ -2287,8 +2219,10 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
if (this.cantWin()) { if (this.cantWin()) {
return false; 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<Player> {
return (41 * (41 + this.getName().hashCode())); 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 class Predicates {
public static final Predicate<Player> NOT_LOST = new Predicate<Player>() {
@Override
public boolean apply(Player p) {
return p.getOutcome() == null || p.getOutcome().hasWon();
}
};
public static Predicate<Player> isType(final PlayerType type) { public static Predicate<Player> isType(final PlayerType type) {
return new Predicate<Player>() { return new Predicate<Player>() {
@Override @Override
@@ -2735,6 +2668,13 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
} }
public static class Accessors { public static class Accessors {
public static Function<Player, LobbyPlayer> FN_GET_LOBBY_PLAYER = new Function<Player, LobbyPlayer>(){
@Override
public LobbyPlayer apply(Player input) {
return input.getLobbyPlayer();
}
};
public static Function<Player, Integer> FN_GET_LIFE = new Function<Player, Integer>(){ public static Function<Player, Integer> FN_GET_LIFE = new Function<Player, Integer>(){
@Override @Override
public Integer apply(Player input) { public Integer apply(Player input) {
@@ -2765,4 +2705,24 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
}; };
} }
} }
/**
* 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!
}
} }

View File

@@ -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;
}
}

View File

@@ -15,14 +15,14 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package forge.game; package forge.game.player;
/** /**
* The Class GamePlayerRating. * The Class GamePlayerRating.
* *
* @author Max * @author Max
*/ */
public class GamePlayerRating { public class PlayerStatistics {
/** The opening hand size. */ /** The opening hand size. */
private int openingHandSize = 7; private int openingHandSize = 7;
@@ -30,42 +30,10 @@ public class GamePlayerRating {
/** The times mulliganed. */ /** The times mulliganed. */
private int timesMulliganed = 0; private int timesMulliganed = 0;
/** The loss reason. */ private int turnsPlayed = 0;
private GameLossReason lossReason = GameLossReason.DidNotLoseYet;
/** The loss spell name. */
private String lossSpellName;
/** private PlayerOutcome outcome;
* 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;
}
/** /**
* Gets the opening hand size. * Gets the opening hand size.
@@ -102,4 +70,20 @@ public class GamePlayerRating {
this.openingHandSize = newHand; 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;
}
} }

View File

@@ -46,7 +46,7 @@ public class PlayerZone extends MyObservable implements IPlayerZone, Observer, j
private static final long serialVersionUID = -5687652485777639176L; private static final long serialVersionUID = -5687652485777639176L;
/** The cards. */ /** The cards. */
protected final List<Card> cardList; protected final List<Card> cardList = new ArrayList<Card>();
protected final Collection<Card> roCardList; protected final Collection<Card> roCardList;
private final ZoneType zoneName; private final ZoneType zoneName;
private final Player player; 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) { public PlayerZone(final ZoneType zone, final Player inPlayer) {
this.zoneName = zone; this.zoneName = zone;
this.player = inPlayer; this.player = inPlayer;
this.cardList = new ArrayList<Card>();
this.roCardList = Collections.unmodifiableCollection(cardList); this.roCardList = Collections.unmodifiableCollection(cardList);
} }

View File

@@ -1,6 +1,7 @@
package forge.game.zone; package forge.game.zone;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -33,7 +34,7 @@ public enum ZoneType {
/** Ante. */ /** Ante. */
Ante(false); Ante(false);
public static final ZoneType[] STATIC_ABILITIES_SOURCE_ZONES = new ZoneType[]{Battlefield, Graveyard, Exile/*, Hand*/}; public static final List<ZoneType> STATIC_ABILITIES_SOURCE_ZONES = Arrays.asList(new ZoneType[]{Battlefield, Graveyard, Exile/*, Hand*/});
private final boolean holdsHiddenInfo; private final boolean holdsHiddenInfo;
private ZoneType(boolean holdsHidden) { private ZoneType(boolean holdsHidden) {

View File

@@ -22,8 +22,8 @@ import java.util.Observer;
import forge.AllZone; import forge.AllZone;
import forge.Card; import forge.Card;
import forge.Singletons;
import forge.control.input.Input; import forge.control.input.Input;
import forge.game.GameState;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZone;
import forge.util.MyObservable; import forge.util.MyObservable;
@@ -41,16 +41,6 @@ public class GuiInput extends MyObservable implements Observer {
/** The input. */ /** The input. */
private Input input; private Input input;
/**
* <p>
* Constructor for GuiInput.
* </p>
*/
public GuiInput() {
AllZone.getInputControl().addObserver(this);
AllZone.getStack().addObserver(this);
Singletons.getModel().getGameState().getPhaseHandler().addObserver(this);
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
@@ -137,4 +127,13 @@ public class GuiInput extends MyObservable implements Observer {
public Input getInput() { public Input getInput() {
return this.input; 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);
}
} }

View File

@@ -46,6 +46,8 @@ public enum CAllDecks implements ICDoc {
public void execute() { importDeck(); } }); public void execute() { importDeck(); } });
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.gui.framework.ICDoc#update() * @see forge.gui.framework.ICDoc#update()
*/ */

View File

@@ -245,4 +245,5 @@ public enum CCurrentDeck implements ICDoc {
} }
return null; return null;
} }
} }

View File

@@ -32,4 +32,5 @@ public interface ICDoc {
* Update whatever content is in the panel. * Update whatever content is in the panel.
*/ */
void update(); void update();
} }

View File

@@ -16,16 +16,16 @@ import javax.swing.SwingWorker;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.deck.DeckgenUtil.DeckTypes; import forge.deck.DeckgenUtil.DeckTypes;
import forge.deck.generate.GenerateThemeDeck; import forge.deck.generate.GenerateThemeDeck;
import forge.game.GameNew;
import forge.game.GameType; import forge.game.GameType;
import forge.game.PlayerStartsGame; import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType; import forge.game.player.PlayerType;
import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO; import forge.gauntlet.GauntletIO;
@@ -250,15 +250,16 @@ public enum CSubmenuGauntletContests implements ICDoc {
@Override @Override
public Object doInBackground() { public Object doInBackground() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
Deck human = gd.getUserDeck();
Deck aiDeck = gd.getDecks().get(gd.getCompleted()); Deck aiDeck = gd.getDecks().get(gd.getCompleted());
Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet);
if (human != null && aiDeck != null) { MatchStartHelper starter = new MatchStartHelper();
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), Lobby lobby = Singletons.getControl().getLobby();
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); 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; return null;
} }

View File

@@ -9,13 +9,14 @@ import java.util.List;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameNew;
import forge.game.GameType; 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.GauntletData;
import forge.gauntlet.GauntletIO; import forge.gauntlet.GauntletIO;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
@@ -103,16 +104,16 @@ public enum CSubmenuGauntletLoad implements ICDoc {
@Override @Override
public Object doInBackground() { public Object doInBackground() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
Deck human = gd.getUserDeck(); MatchStartHelper starter = new MatchStartHelper();
Deck aiDeck = gd.getDecks().get(gd.getCompleted()); Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), gd.getUserDeck());
starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck);
Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(GameType.Gauntlet, starter.getPlayerMap());
if (human != null && aiDeck != null) { mc.startRound();
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
}
return null; return null;
} }

View File

@@ -16,16 +16,16 @@ import javax.swing.SwingWorker;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.deck.DeckgenUtil.DeckTypes; import forge.deck.DeckgenUtil.DeckTypes;
import forge.deck.generate.GenerateThemeDeck; import forge.deck.generate.GenerateThemeDeck;
import forge.game.GameNew;
import forge.game.GameType; import forge.game.GameType;
import forge.game.PlayerStartsGame; import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType; import forge.game.player.PlayerType;
import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO; import forge.gauntlet.GauntletIO;
@@ -293,15 +293,16 @@ public enum CSubmenuGauntletQuick implements ICDoc {
@Override @Override
public Object doInBackground() { public Object doInBackground() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), gd.getUserDeck());
starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck);
Deck human = gd.getUserDeck(); MatchController mc = Singletons.getModel().getMatch();
Deck aiDeck = gd.getDecks().get(gd.getCompleted()); mc.initMatch(GameType.Gauntlet, starter.getPlayerMap());
if (human != null && aiDeck != null) { mc.startRound();
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
}
return null; return null;
} }

View File

@@ -2,23 +2,21 @@ package forge.gui.home.multiplayer;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.game.GameNew;
import forge.game.GameType; import forge.game.GameType;
import forge.game.PlayerStartsGame; import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType; import forge.game.player.PlayerType;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.CMatchUI;
/** /**
* Controls the deck editor submenu option in the home UI. * 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 humanDeck = DeckgenUtil.getRandomColorDeck(PlayerType.HUMAN);
Deck aiDeck = DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER); Deck aiDeck = DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER);
CMatchUI.SINGLETON_INSTANCE.initMatch(numFields, numHands); MatchStartHelper starter = new MatchStartHelper();
Singletons.getModel().getMatchState().setGameType(GameType.Constructed); 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();
if (humanDeck != null && aiDeck != null) {
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
}
return null; return null;
} }

View File

@@ -8,17 +8,17 @@ import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import forge.AllZone;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameNew;
import forge.game.GameType; 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.SOverlayUtils;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.controllers.CEditorQuestCardShop; import forge.gui.deckeditor.controllers.CEditorQuestCardShop;
import forge.gui.match.CMatchUI;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestEvent; import forge.quest.QuestEvent;
@@ -260,15 +260,14 @@ public class SSubmenuQuestUtil {
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() { final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override @Override
public Object doInBackground() { public Object doInBackground() {
Singletons.getModel().getMatchState().setGameType(GameType.Quest);
qData.getChallengesManager().randomizeOpponents(); qData.getChallengesManager().randomizeOpponents();
qData.getDuelsManager().randomizeOpponents(); qData.getDuelsManager().randomizeOpponents();
qData.setCurrentEvent(event); qData.setCurrentEvent(event);
qData.save(); qData.save();
PlayerStartsGame p1 = new PlayerStartsGame(AllZone.getHumanPlayer(), SSubmenuQuestUtil.getCurrentDeck()); PlayerStartConditions humanStart = new PlayerStartConditions(SSubmenuQuestUtil.getCurrentDeck());
PlayerStartsGame p2 = new PlayerStartsGame(AllZone.getComputerPlayer(), event.getEventDeck()); PlayerStartConditions aiStart = new PlayerStartConditions(event.getEventDeck());
if (qData.getMode() == QuestMode.Fantasy) { if (qData.getMode() == QuestMode.Fantasy) {
int lifeAI = 20; int lifeAI = 20;
@@ -282,14 +281,21 @@ public class SSubmenuQuestUtil {
} }
} }
p1.initialLives = qData.getAssets().getLife(qData.getMode()) + extraLifeHuman; humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman);
p1.cardsOnBattlefield = QuestUtil.getHumanStartingCards(qData, event); humanStart.setCardsOnTable(QuestUtil.getHumanStartingCards(qData, event));
p2.initialLives = lifeAI; aiStart.setStartingLife(lifeAI);
p2.cardsOnBattlefield = QuestUtil.getComputerStartingCards(event); aiStart.setCardsOnTable(QuestUtil.getComputerStartingCards(event));
} // End isFantasy } // End isFantasy
CMatchUI.SINGLETON_INSTANCE.initMatch(event.getIconFilename()); MatchStartHelper msh = new MatchStartHelper();
GameNew.newGame(p1, p2); 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; return null;
} }

View File

@@ -17,19 +17,18 @@ import javax.swing.SwingWorker;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.deck.generate.GenerateThemeDeck; import forge.deck.generate.GenerateThemeDeck;
import forge.game.GameNew;
import forge.game.GameType; import forge.game.GameType;
import forge.game.PlayerStartsGame; import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType; import forge.game.player.PlayerType;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.CMatchUI;
import forge.gui.toolbox.ExperimentalLabel; import forge.gui.toolbox.ExperimentalLabel;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
@@ -319,13 +318,15 @@ public enum CSubmenuConstructed implements ICDoc {
Deck humanDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstUserDecks(), PlayerType.HUMAN); Deck humanDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstUserDecks(), PlayerType.HUMAN);
Deck aiDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstDecksAI(), PlayerType.COMPUTER); Deck aiDeck = generateDeck(VSubmenuConstructed.SINGLETON_INSTANCE.getLstDecksAI(), PlayerType.COMPUTER);
CMatchUI.SINGLETON_INSTANCE.initMatch(null); MatchStartHelper starter = new MatchStartHelper();
Singletons.getModel().getMatchState().setGameType(GameType.Constructed); 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();
if (humanDeck != null && aiDeck != null) {
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
}
return null; return null;
} }

View File

@@ -13,19 +13,21 @@ import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.control.Lobby;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.game.GameNew;
import forge.game.GameType; 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.BoosterDraft;
import forge.game.limited.CardPoolLimitation; import forge.game.limited.CardPoolLimitation;
import forge.game.player.LobbyPlayer;
import forge.game.player.PlayerType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.controllers.CEditorDraftingProcess; import forge.gui.deckeditor.controllers.CEditorDraftingProcess;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.CMatchUI;
/** /**
* Controls the draft submenu in the home UI. * Controls the draft submenu in the home UI.
@@ -44,6 +46,7 @@ public enum CSubmenuDraft implements ICDoc {
VSubmenuDraft.SINGLETON_INSTANCE.getBtnStart().setEnabled(true); VSubmenuDraft.SINGLETON_INSTANCE.getBtnStart().setEnabled(true);
} }
}; };
private LobbyPlayer[] opponents;
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update() * @see forge.control.home.IControlSubmenu#update()
@@ -90,16 +93,15 @@ public enum CSubmenuDraft implements ICDoc {
private void startGame() { private void startGame() {
final boolean gauntlet = VSubmenuDraft.SINGLETON_INSTANCE.getRadSingle().isSelected() ? false : true; final boolean gauntlet = VSubmenuDraft.SINGLETON_INSTANCE.getRadSingle().isSelected() ? false : true;
final Deck humanDeck = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck();
final Deck human = VSubmenuDraft.SINGLETON_INSTANCE.getLstDecks().getSelectedDeck();
final int aiIndex = (int) Math.floor(Math.random() * 8); final int aiIndex = (int) Math.floor(Math.random() * 8);
if (human == null) { if (humanDeck == null) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
"No deck selected for human!\r\n(You may need to build a new deck.)", "No deck selected for human!\r\n(You may need to build a new deck.)",
"No deck", JOptionPane.ERROR_MESSAGE); "No deck", JOptionPane.ERROR_MESSAGE);
return; return;
} else if (!human.meetsGameTypeRequirements(GameType.Draft)) { } else if (!humanDeck.meetsGameTypeRequirements(GameType.Draft)) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
"The selected deck doesn't have enough cards to play (minimum 40)." "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.", + "\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(); AllZone.getGauntlet().resetGauntletDraft();
if (gauntlet) { if (gauntlet) {
int rounds = Singletons.getModel().getDecks().getDraft().get(human.getName()).getAiDecks().size(); int rounds = Singletons.getModel().getDecks().getDraft().get(humanDeck.getName()).getAiDecks().size();
AllZone.getGauntlet().launch(rounds, human, GameType.Draft); AllZone.getGauntlet().launch(rounds, humanDeck, GameType.Draft);
return; return;
} }
@@ -126,17 +128,20 @@ public enum CSubmenuDraft implements ICDoc {
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() { final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override @Override
public Object doInBackground() { 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); Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex);
if (aiDeck == null) { if (aiDeck == null) {
throw new IllegalStateException("Draft: Computer deck is null!"); throw new IllegalStateException("Draft: Computer deck is null!");
} }
CMatchUI.SINGLETON_INSTANCE.initMatch(null); MatchStartHelper starter = new MatchStartHelper();
Singletons.getModel().getMatchState().setGameType(GameType.Draft); starter.addPlayer(Singletons.getControl().getLobby().findLocalPlayer(PlayerType.HUMAN), humanDeck);
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), starter.addPlayer(opponents[aiIndex], aiDeck);
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(GameType.Draft, starter.getPlayerMap());
mc.startRound();
return null; return null;
} }
@@ -180,6 +185,22 @@ public enum CSubmenuDraft implements ICDoc {
FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED);
CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(draft); 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) /* (non-Javadoc)

View File

@@ -20,7 +20,6 @@ package forge.gui.match;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.GameEntity; import forge.GameEntity;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
@@ -46,16 +45,6 @@ public enum CMatchUI implements CardContainer {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
/**
* Due to be deprecated with new multiplayer changes. Doublestrike 13-10-12.
*
* @param strAvatarIcon &emsp; 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 * Instantiates at a match with a specified number of players
* and hands. * and hands.
@@ -63,7 +52,7 @@ public enum CMatchUI implements CardContainer {
* @param numFieldPanels int * @param numFieldPanels int
* @param numHandPanels int * @param numHandPanels int
*/ */
public void initMatch(int numFieldPanels, int numHandPanels) { public void initMatch(final List<Player> players, Player localPlayer) {
// TODO fix for use with multiplayer // TODO fix for use with multiplayer
// Update avatars // Update avatars
/*final String[] indices = Singletons.getModel().getPreferences().getPref(FPref.UI_AVATARS).split(","); /*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()) { for (VField view : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
final Image img; final Image img;
// Update AI quest icon // 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; String filename = ForgeProps.getFile(NewConstants.IMAGE_ICON) + File.separator;
if (strAvatarIcon != null) { if (strAvatarIcon != null) {
@@ -94,39 +83,37 @@ public enum CMatchUI implements CardContainer {
view.getLblAvatar().getResizeTimer().start(); 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<VField> fields = new ArrayList<VField>(); final List<VField> fields = new ArrayList<VField>();
for (int i = 0; i < numFieldPanels; i++) {
switch (i) { fields.add(0, new VField(EDocID.valueOf("FIELD_0"), localPlayer));
case 0:
fields.add(0, new VField(EDocID.FIELD_0, AllZone.getHumanPlayer()));
fields.get(0).getLayoutControl().initialize(); fields.get(0).getLayoutControl().initialize();
break;
case 1:
fields.add(1, new VField(EDocID.FIELD_1, AllZone.getComputerPlayer())); int i = 1;
fields.get(1).getLayoutControl().initialize(); for (Player p : players) {
break; if (p.equals(localPlayer)) continue;
default:
// A field must be initialized after it's instantiated, to update player info. // A field must be initialized after it's instantiated, to update player info.
// No player, no init. // No player, no init.
fields.add(i, new VField(EDocID.valueOf("FIELD_" + i), null)); VField f = new VField(EDocID.valueOf("FIELD_" + i), p);
} f.getLayoutControl().initialize();
fields.add(f);
i++;
} }
// Instantiate all required hand slots (user at 0) // Instantiate all required hand slots (user at 0)
final List<VHand> hands = new ArrayList<VHand>(); final List<VHand> hands = new ArrayList<VHand>();
for (int i = 0; i < numHandPanels; i++) { VHand newHand = new VHand(EDocID.HAND_0, localPlayer);
switch (i) { newHand.getLayoutControl().initialize();
case 0: hands.add(newHand);
// A hand must be initialized after it's instantiated, to update player info.
// No player, no init. // Max: 2+ hand are needed at 2HG (but this is quite far now) - yet it's nice to have this possibility
hands.add(0, new VHand(EDocID.HAND_0, AllZone.getHumanPlayer())); // for (int i = 0; i < numHandPanels; i++) {
hands.get(0).getLayoutControl().initialize(); // switch (i) {
break; // hands.add(i, new VHand(EDocID.valueOf("HAND_" + i), null));
default: // }
hands.add(i, new VHand(EDocID.valueOf("HAND_" + i), null)); // }
}
}
// Replace old instances // Replace old instances
VMatchUI.SINGLETON_INSTANCE.setFieldViews(fields); VMatchUI.SINGLETON_INSTANCE.setFieldViews(fields);

View File

@@ -7,15 +7,12 @@ import java.util.List;
import javax.swing.JButton; import javax.swing.JButton;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.control.FControl; import forge.control.FControl;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameNew; import forge.game.GameOutcome;
import forge.game.GameSummary;
import forge.game.GameType; import forge.game.GameType;
import forge.game.PlayerStartsGame;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
@@ -68,14 +65,24 @@ public class ControlWinLose {
/** Action performed when "continue" button is pressed in default win/lose UI. */ /** Action performed when "continue" button is pressed in default win/lose UI. */
public void actionOnContinue() { public void actionOnContinue() {
SOverlayUtils.hideOverlay(); 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. */ /** Action performed when "restart" button is pressed in default win/lose UI. */
public void actionOnRestart() { public void actionOnRestart() {
Singletons.getModel().getMatchState().reset();
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
startNextRound(); saveOptions();
Singletons.getModel().getMatch().replayRound();
} }
/** Action performed when "quit" button is pressed in default win/lose UI. */ /** Action performed when "quit" button is pressed in default win/lose UI. */
@@ -89,9 +96,7 @@ public class ControlWinLose {
} }
// Reset other stuff // Reset other stuff
Singletons.getModel().getMatchState().reset(); saveOptions();
Singletons.getModel().getPreferences().writeMatchPreferences();
Singletons.getModel().getPreferences().save();
Singletons.getControl().changeState(FControl.HOME_SCREEN); Singletons.getControl().changeState(FControl.HOME_SCREEN);
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
@@ -100,22 +105,9 @@ public class ControlWinLose {
* Either continues or restarts a current game. May be overridden for use * Either continues or restarts a current game. May be overridden for use
* with other game modes. * with other game modes.
*/ */
public void startNextRound() { public void saveOptions() {
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();
}
Singletons.getModel().getPreferences().writeMatchPreferences(); Singletons.getModel().getPreferences().writeMatchPreferences();
Singletons.getModel().getPreferences().save(); 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,15 +116,12 @@ public class ControlWinLose {
* @param cDeck * @param cDeck
*/ */
private void executeAnte() { private void executeAnte() {
List<GameSummary> games = Singletons.getModel().getMatchState().getGamesPlayed(); List<GameOutcome> games = Singletons.getModel().getMatch().getPlayedGames();
if (games.isEmpty()) { if ( games.isEmpty() ) return;
return;
} GameOutcome lastGame = games.get(games.size()-1);
GameSummary lastGame = games.get(games.size() - 1); for (Player p: Singletons.getModel().getGameState().getPlayers()) {
for (Player p : Singletons.getModel().getGameState().getPlayers()) { if (!p.getName().equals(lastGame.getWinner())) continue; // not a loser
if (!p.getName().equals(lastGame.getWinner())) {
continue; // not a loser
}
// remove all the lost cards from owners' decks // remove all the lost cards from owners' decks
List<CardPrinted> losses = new ArrayList<CardPrinted>(); List<CardPrinted> losses = new ArrayList<CardPrinted>();
@@ -142,7 +131,7 @@ public class ControlWinLose {
} }
List<Card> compAntes = loser.getCardsIn(ZoneType.Ante); List<Card> compAntes = loser.getCardsIn(ZoneType.Ante);
Deck cDeck = loser.getDeck(); Deck cDeck = Singletons.getModel().getMatch().getPlayersDeck(loser.getLobbyPlayer());
for (Card c : compAntes) { for (Card c : compAntes) {
CardPrinted toRemove = CardDb.instance().getCard(c); CardPrinted toRemove = CardDb.instance().getCard(c);
@@ -152,10 +141,11 @@ public class ControlWinLose {
// offer to winner, if he is human // offer to winner, if he is human
if (p.isHuman()) { if (p.isHuman()) {
List<CardPrinted> o = GuiChoose.noneOrMany("Select cards to add to your deck", losses); List<CardPrinted> chosen = GuiChoose.noneOrMany("Select cards to add to your deck", losses);
if (null != o) { if (null != chosen) {
for (CardPrinted c : o) { Deck d = Singletons.getModel().getMatch().getPlayersDeck(p.getLobbyPlayer());
p.getDeck().getMain().add(c); for (CardPrinted c : chosen) {
d.getMain().add(c);
} }
} }
} }

View File

@@ -26,9 +26,9 @@ import javax.swing.SwingConstants;
import forge.AllZone; import forge.AllZone;
import forge.Singletons; import forge.Singletons;
import forge.game.MatchController;
import forge.game.limited.GauntletMini; import forge.game.limited.GauntletMini;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.model.FMatchState;
/** /**
* The Win/Lose handler for 'gauntlet' type tournament * The Win/Lose handler for 'gauntlet' type tournament
@@ -47,7 +47,7 @@ public class GauntletWinLose extends ControlWinLose {
private JLabel lblTemp1; private JLabel lblTemp1;
private JLabel lblTemp2; private JLabel lblTemp2;
private final FMatchState matchState; private final MatchController matchState;
/** /**
* Instantiates a new gauntlet win/lose handler. * Instantiates a new gauntlet win/lose handler.
@@ -58,8 +58,8 @@ public class GauntletWinLose extends ControlWinLose {
super(view0); super(view0);
this.view = view0; this.view = view0;
gauntlet = AllZone.getGauntlet(); gauntlet = AllZone.getGauntlet();
matchState = Singletons.getModel().getMatchState(); matchState = Singletons.getModel().getMatch();
this.wonMatch = matchState.isMatchWonBy(AllZone.getHumanPlayer()); 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(); gauntlet.addWin();
} }
else { else {

View File

@@ -25,13 +25,14 @@ import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.AllZone; import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.MatchController;
import forge.game.player.LobbyPlayer;
import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO; import forge.gauntlet.GauntletIO;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.model.FMatchState;
import forge.model.FModel; import forge.model.FModel;
/** /**
@@ -57,7 +58,7 @@ public class OtherGauntletWinLose extends ControlWinLose {
@Override @Override
public final boolean populateCustomPanel() { public final boolean populateCustomPanel() {
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final FMatchState matchState = FModel.SINGLETON_INSTANCE.getMatchState(); final MatchController match = FModel.SINGLETON_INSTANCE.getMatch();
final List<String> lstEventNames = gd.getEventNames(); final List<String> lstEventNames = gd.getEventNames();
final List<Deck> lstDecks = gd.getDecks(); final List<Deck> lstDecks = gd.getDecks();
final List<String> lstEventRecords = gd.getEventRecords(); final List<String> lstEventRecords = gd.getEventRecords();
@@ -78,15 +79,14 @@ public class OtherGauntletWinLose extends ControlWinLose {
// the player can restart Forge to replay a match. // the player can restart Forge to replay a match.
// Pretty sure this can't be fixed until in-game states can be // Pretty sure this can't be fixed until in-game states can be
// saved. Doublestrike 07-10-12 // saved. Doublestrike 07-10-12
if (matchState.isMatchOver()) { LobbyPlayer questPlayer = Singletons.getControl().getLobby().getQuestPlayer();
if (match.isMatchOver()) {
// In all cases, update stats. // In all cases, update stats.
lstEventRecords.set(gd.getCompleted(), lstEventRecords.set(gd.getCompleted(), match.getGamesWonBy(questPlayer) + " - " + ( match.getPlayedGames().size() - match.getGamesWonBy(questPlayer) ) );
matchState.countGamesWonBy(AllZone.getHumanPlayer())
+ " - " + matchState.countGamesWonBy(AllZone.getComputerPlayer()));
gd.setCompleted(gd.getCompleted() + 1); gd.setCompleted(gd.getCompleted() + 1);
// Win match case // Win match case
if (matchState.isMatchWonBy(AllZone.getHumanPlayer())) { if (match.isWonBy(questPlayer)) {
// Gauntlet complete: Remove save file // Gauntlet complete: Remove save file
if (gd.getCompleted() == lstDecks.size()) { if (gd.getCompleted() == lstDecks.size()) {
lblGraphic = new FLabel.Builder() lblGraphic = new FLabel.Builder()
@@ -112,8 +112,6 @@ public class OtherGauntletWinLose extends ControlWinLose {
else { else {
gd.stamp(); gd.stamp();
GauntletIO.saveGauntlet(gd); GauntletIO.saveGauntlet(gd);
matchState.reset();
AllZone.getComputerPlayer().setDeck(lstDecks.get(gd.getCompleted()));
this.getView().getBtnContinue().setVisible(true); this.getView().getBtnContinue().setVisible(true);
this.getView().getBtnContinue().setEnabled(true); this.getView().getBtnContinue().setEnabled(true);

View File

@@ -16,8 +16,6 @@
*/ */
package forge.gui.match; package forge.gui.match;
import forge.AllZone;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import forge.Card; import forge.Card;
@@ -30,10 +28,11 @@ import forge.card.UnOpenedProduct;
import forge.game.GameEndReason; import forge.game.GameEndReason;
import forge.game.GameFormat; import forge.game.GameFormat;
import forge.game.GameLossReason; import forge.game.GameLossReason;
import forge.game.GameNew; import forge.game.GameOutcome;
import forge.game.GamePlayerRating; import forge.game.MatchController;
import forge.game.GameSummary; import forge.game.player.LobbyPlayer;
import forge.game.PlayerStartsGame; import forge.game.player.PlayerOutcome;
import forge.game.player.PlayerStatistics;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
@@ -42,16 +41,13 @@ import forge.gui.SOverlayUtils;
import forge.gui.home.quest.CSubmenuChallenges; import forge.gui.home.quest.CSubmenuChallenges;
import forge.gui.home.quest.CSubmenuDuels; import forge.gui.home.quest.CSubmenuDuels;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.item.CardDb;
import forge.item.CardPrinted; import forge.item.CardPrinted;
import forge.model.FMatchState;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestEventChallenge; import forge.quest.QuestEventChallenge;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestEvent; import forge.quest.QuestEvent;
import forge.quest.QuestMode;
import forge.quest.QuestUtil;
import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestAssets;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.ReadPriceList; import forge.quest.io.ReadPriceList;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -63,6 +59,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import javax.swing.BorderFactory; 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_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 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 QuestController qData;
private final transient QuestEvent qEvent; private final transient QuestEvent qEvent;
@@ -104,53 +101,13 @@ public class QuestWinLoseHandler extends ControlWinLose {
public QuestWinLoseHandler(final ViewWinLose view0) { public QuestWinLoseHandler(final ViewWinLose view0) {
super(view0); super(view0);
this.view = view0; this.view = view0;
matchState = Singletons.getModel().getMatchState(); match = Singletons.getModel().getMatch();
qData = Singletons.getModel().getQuest(); qData = Singletons.getModel().getQuest();
qEvent = qData.getCurrentEvent(); 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); this.isAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE);
} }
/**
* <p>
* startNextRound.
* </p>
* 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();
}
}
/** /**
* <p> * <p>
@@ -165,28 +122,29 @@ public class QuestWinLoseHandler extends ControlWinLose {
public final boolean populateCustomPanel() { public final boolean populateCustomPanel() {
this.getView().getBtnRestart().setVisible(false); this.getView().getBtnRestart().setVisible(false);
qData.getCards().resetNewList(); qData.getCards().resetNewList();
QuestController qc = Singletons.getModel().getQuest();
LobbyPlayer questPlayer = Singletons.getControl().getLobby().getQuestPlayer();
if (isAnte) {
//do per-game actions //do per-game actions
if (matchState.hasWonLastGame(AllZone.getHumanPlayer().getName())) { boolean isHumanWinner = match.isWonBy(questPlayer);
if (isAnte) { final List<CardPrinted> anteCards = new ArrayList<CardPrinted>();
final List<Card> antes = AllZone.getComputerPlayer().getCardsIn(ZoneType.Ante); for( Player p : Singletons.getModel().getGameState().getPlayers() ) {
final List<CardPrinted> antesPrinted = Singletons.getModel().getMatchState().addAnteWon(antes); if (p.getLobbyPlayer().equals(questPlayer) == isHumanWinner) continue;
this.anteWon(antesPrinted); for(Card c : p.getCardsIn(ZoneType.Ante))
anteCards.add(CardDb.instance().getCard(c));
} }
if (isHumanWinner) {
qc.getCards().addAllCards(anteCards);
this.anteWon(anteCards);
} else { } else {
if (isAnte) { for(CardPrinted c : anteCards)
final List<Card> antes = AllZone.getHumanPlayer().getCardsIn(ZoneType.Ante); qc.getCards().loseCard(c);
final List<CardPrinted> antesPrinted = Singletons.getModel().getMatchState().addAnteLost(antes); this.anteLost(anteCards);
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 (!matchState.isMatchOver()) { if (!match.isMatchOver()) {
this.getView().getBtnQuit().setText("Quit (15 Credits)"); this.getView().getBtnQuit().setText("Quit (15 Credits)");
return isAnte; return isAnte;
} else { } 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; return true;
} }
@@ -329,7 +283,6 @@ public class QuestWinLoseHandler extends ControlWinLose {
qData.getAchievements().addChallengesPlayed(); qData.getAchievements().addChallengesPlayed();
} }
matchState.reset();
CSubmenuDuels.SINGLETON_INSTANCE.update(); CSubmenuDuels.SINGLETON_INSTANCE.update();
CSubmenuChallenges.SINGLETON_INSTANCE.update(); CSubmenuChallenges.SINGLETON_INSTANCE.update();
@@ -384,16 +337,25 @@ public class QuestWinLoseHandler extends ControlWinLose {
sb.append(diff + " opponent: " + credBase + " credits.<br>"); sb.append(diff + " opponent: " + credBase + " credits.<br>");
// Gameplay bonuses (for each game win) // Gameplay bonuses (for each game win)
boolean hasNeverLost = true; boolean hasNeverLost = true;
final Player computer = AllZone.getComputerPlayer();
for (final GameSummary game : matchState.getGamesPlayed()) { LobbyPlayer localHuman = Singletons.getControl().getLobby().getQuestPlayer();
if (game.isWinner(computer.getName())) { for (final GameOutcome game : match.getPlayedGames()) {
if (!game.isWinner(localHuman)) {
hasNeverLost = false; hasNeverLost = false;
continue; // no rewards for losing a game continue; // no rewards for losing a game
} }
// Alternate win // Alternate win
final GamePlayerRating aiRating = game.getPlayerRating(computer.getName());
final GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName()); // final PlayerStatistics aiRating = game.getStatistics(computer.getName());
final GameLossReason whyAiLost = aiRating.getLossReason(); PlayerStatistics humanRating = null;
for(Entry<LobbyPlayer, PlayerStatistics> 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); final int altReward = this.getCreditsRewardForAltWin(whyAiLost);
if (altReward > 0) { if (altReward > 0) {
@@ -409,7 +371,7 @@ public class QuestWinLoseHandler extends ControlWinLose {
winConditionName = "Milled"; winConditionName = "Milled";
break; break;
case SpellEffect: case SpellEffect:
winConditionName = aiRating.getLossSpellName(); winConditionName = outcome.loseConditionSpell;
break; break;
default: default:
break; break;
@@ -420,6 +382,7 @@ public class QuestWinLoseHandler extends ControlWinLose {
sb.append(String.format("Alternate win condition: <u>%s</u>! " + "Bonus: %d credits.<br>", sb.append(String.format("Alternate win condition: <u>%s</u>! " + "Bonus: %d credits.<br>",
winConditionName, 50)); winConditionName, 50));
} }
}
// Mulligan to zero // Mulligan to zero
final int cntCardsHumanStartedWith = humanRating.getOpeningHandSize(); final int cntCardsHumanStartedWith = humanRating.getOpeningHandSize();
final int mulliganReward = Singletons.getModel().getQuestPreferences() final int mulliganReward = Singletons.getModel().getQuestPreferences()
@@ -945,6 +908,8 @@ public class QuestWinLoseHandler extends ControlWinLose {
* @return int * @return int
*/ */
private int getCreditsRewardForAltWin(final GameLossReason whyAiLost) { private int getCreditsRewardForAltWin(final GameLossReason whyAiLost) {
if ( null == whyAiLost) // Felidar, Helix Pinnacle, etc.
return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED);
switch (whyAiLost) { switch (whyAiLost) {
case LifeReachedZero: case LifeReachedZero:
return 0; // nothing special here, ordinary kill return 0; // nothing special here, ordinary kill
@@ -952,8 +917,6 @@ public class QuestWinLoseHandler extends ControlWinLose {
return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_MILLED); return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_MILLED);
case Poisoned: case Poisoned:
return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_POISON); 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. case SpellEffect: // Door to Nothingness, etc.
return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED); return Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.REWARDS_UNDEFEATED);
default: default:

View File

@@ -12,9 +12,8 @@ import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.AllZone; import forge.AllZone;
import forge.Singletons; import forge.Singletons;
import forge.game.GameType; import forge.game.MatchController;
import forge.game.phase.PhaseHandler; import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.gui.toolbox.FButton; import forge.gui.toolbox.FButton;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
@@ -22,7 +21,6 @@ import forge.gui.toolbox.FOverlay;
import forge.gui.toolbox.FScrollPane; import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextArea; import forge.gui.toolbox.FTextArea;
import forge.model.FMatchState;
import forge.properties.ForgeProps; import forge.properties.ForgeProps;
import forge.properties.NewConstants.Lang.GuiWinLose.WinLoseText; import forge.properties.NewConstants.Lang.GuiWinLose.WinLoseText;
@@ -38,7 +36,7 @@ public class ViewWinLose {
/** */ /** */
public ViewWinLose() { public ViewWinLose() {
final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel(); 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 pnlLeft = new JPanel();
final JPanel pnlRight = new JPanel(); final JPanel pnlRight = new JPanel();
@@ -52,23 +50,26 @@ public class ViewWinLose {
btnRestart = new FButton(); btnRestart = new FButton();
btnQuit = 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. // Control of the win/lose is handled differently for various game modes.
ControlWinLose control; ControlWinLose control = null;
if (matchState.getGameType() == GameType.Quest) { switch (Singletons.getModel().getMatch().getGameType()) {
case Quest:
control = new QuestWinLoseHandler(this); control = new QuestWinLoseHandler(this);
} break;
else if (matchState.getGameType() == GameType.Sealed case Draft:
|| (matchState.getGameType() == GameType.Draft && AllZone.getGauntlet().isGauntletDraft())) { if (!AllZone.getGauntlet().isGauntletDraft()) break;
case Sealed:
control = new GauntletWinLose(this); control = new GauntletWinLose(this);
} break;
else if (matchState.getGameType() == GameType.Gauntlet) { case Gauntlet:
control = new OtherGauntletWinLose(this); control = new OtherGauntletWinLose(this);
break;
} }
else { if( null == control)
control = new ControlWinLose(this); control = new ControlWinLose(this);
}
pnlLeft.setOpaque(false); pnlLeft.setOpaque(false);
pnlRight.setOpaque(false); pnlRight.setOpaque(false);
@@ -94,24 +95,22 @@ public class ViewWinLose {
btnQuit.setText(ForgeProps.getLocalized(WinLoseText.QUIT)); btnQuit.setText(ForgeProps.getLocalized(WinLoseText.QUIT));
btnQuit.setFont(FSkin.getFont(22)); 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.getBtnContinue().setEnabled(false);
this.getBtnQuit().grabFocus(); this.getBtnQuit().grabFocus();
} }
// Show Wins and Loses // Show Wins and Loses
final int humanWins = matchState.countGamesWonBy(human); final int humanWins = match.getGamesWonBy(human);
final int humanLosses = matchState.getGamesPlayedCount() - humanWins; final int humanLosses = match.getPlayedGames().size() - humanWins;
lblStats.setText(ForgeProps.getLocalized(WinLoseText.WON) + humanWins lblStats.setText(ForgeProps.getLocalized(WinLoseText.WON) + humanWins
+ ForgeProps.getLocalized(WinLoseText.LOST) + humanLosses); + ForgeProps.getLocalized(WinLoseText.LOST) + humanLosses);
// Show "You Won" or "You Lost" // Show "You Won" or "You Lost"
if (matchState.hasWonLastGame(human.getName())) { if (match.getLastGameOutcome().isWinner(human)) {
lblTitle.setText(ForgeProps.getLocalized(WinLoseText.WIN)); lblTitle.setText(ForgeProps.getLocalized(WinLoseText.WIN));
} else { } else {
lblTitle.setText(ForgeProps.getLocalized(WinLoseText.LOSE)); lblTitle.setText(ForgeProps.getLocalized(WinLoseText.LOSE));

View File

@@ -34,5 +34,4 @@ public enum CAntes implements ICDoc {
@Override @Override
public void update() { public void update() {
} }
} }

View File

@@ -36,5 +36,4 @@ public enum CCombat implements ICDoc {
public void update() { public void update() {
VCombat.SINGLETON_INSTANCE.updateCombat(""); VCombat.SINGLETON_INSTANCE.updateCombat("");
} }
} }

View File

@@ -37,7 +37,7 @@ public enum CDetail implements ICDoc {
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private Card currentCard = null; private Card currentCard = null;
private InventoryItem item = null; //private InventoryItem item = null;
/** /**
* Shows card details and/or picture in sidebar cardview tabber. * Shows card details and/or picture in sidebar cardview tabber.
@@ -45,7 +45,7 @@ public enum CDetail implements ICDoc {
* @param c &emsp; Card object * @param c &emsp; Card object
*/ */
public void showCard(final Card c) { public void showCard(final Card c) {
this.item = null; //this.item = null;
this.currentCard = c; this.currentCard = c;
VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(c != null && c.isDoubleFaced() ? true : false); VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(c != null && c.isDoubleFaced() ? true : false);
VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(c); VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(c);
@@ -54,7 +54,7 @@ public enum CDetail implements ICDoc {
public void showCard(InventoryItem item) { 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 // 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; this.currentCard = null;
VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false); VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false);
VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(null); VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(null);

View File

@@ -137,7 +137,7 @@ public enum CDock implements ICDoc {
* View deck list. * View deck list.
*/ */
private void viewDeckList() { private void viewDeckList() {
showDeck(Singletons.getControl().getPlayer().getDeck()); showDeck(Singletons.getModel().getMatch().getPlayersDeck(Singletons.getControl().getPlayer().getLobbyPlayer()));
} }
/** Attack with everyone. */ /** Attack with everyone. */
@@ -290,4 +290,5 @@ public enum CDock implements ICDoc {
@Override @Override
public void update() { public void update() {
} }
} }

View File

@@ -3,8 +3,8 @@ package forge.gui.match.controllers;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.game.GameState;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.views.VLog; import forge.gui.match.views.VLog;
@@ -31,7 +31,11 @@ public enum CLog implements ICDoc, Observer {
*/ */
@Override @Override
public void initialize() { public void initialize() {
AllZone.getGameLog().addObserver(this);
}
public void subscribe(GameState currentGame) {
currentGame.getGameLog().addObserver(this);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -22,6 +22,8 @@ import java.awt.event.ActionListener;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.game.GameState;
import forge.game.MatchController;
import forge.gui.GuiInput; import forge.gui.GuiInput;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SDisplayUtil;
@@ -36,7 +38,7 @@ public enum CMessage implements ICDoc {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private final GuiInput inputControl = new GuiInput(); private GuiInput inputControl = new GuiInput();
private final ActionListener actCancel = new ActionListener() { private final ActionListener actCancel = new ActionListener() {
@Override @Override
public void actionPerformed(final ActionEvent evt) { public void actionPerformed(final ActionEvent evt) {
@@ -59,6 +61,10 @@ public enum CMessage implements ICDoc {
} }
}; };
public void subscribe(GameState game) {
inputControl.subscribe(game);
}
@Override @Override
public void initialize() { public void initialize() {
VMessage.SINGLETON_INSTANCE.getBtnCancel().removeActionListener(actCancel); VMessage.SINGLETON_INSTANCE.getBtnCancel().removeActionListener(actCancel);
@@ -82,13 +88,15 @@ public enum CMessage implements ICDoc {
VMessage.SINGLETON_INSTANCE.getTarMessage().setText(s0); VMessage.SINGLETON_INSTANCE.getTarMessage().setText(s0);
} }
/** Updates counter label in message area. */ /** Updates counter label in message area.
public void updateGameInfo() { * @param match
* @param gameState */
public void updateGameInfo(MatchController match) {
VMessage.SINGLETON_INSTANCE.getLblGames().setText( VMessage.SINGLETON_INSTANCE.getLblGames().setText(
Singletons.getModel().getMatchState().getGameType().toString() + ": Game #" match.getGameType().toString() + ": Game #"
+ (Singletons.getModel().getMatchState().getGamesPlayedCount() + 1) + (match.getPlayedGames().size() + 1)
+ " of " + Singletons.getModel().getMatchState().getGamesPerMatch() + " of " + match.getGamesPerMatch()
+ ", turn " + Singletons.getModel().getGameSummary().getLastTurnNumber()); + ", turn " + match.getCurrentGame().getTurnNumber());
} }
/** Flashes animation on input panel if play is currently waiting on input. */ /** Flashes animation on input panel if play is currently waiting on input. */

View File

@@ -1,7 +1,8 @@
package forge.gui.match.controllers; package forge.gui.match.controllers;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.Singletons;
import forge.game.player.Player;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.views.VPlayers; import forge.gui.match.views.VPlayers;
@@ -35,8 +36,9 @@ public enum CPlayers implements ICDoc {
*/ */
@Override @Override
public void update() { public void update() {
VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(AllZone.getComputerPlayer()); for(Player p : Singletons.getModel().getGameState().getPlayers())
VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(AllZone.getHumanPlayer()); VPlayers.SINGLETON_INSTANCE.updatePlayerLabels(p);
VPlayers.SINGLETON_INSTANCE.updateStormLabel(); VPlayers.SINGLETON_INSTANCE.updateStormLabel();
} }

View File

@@ -3,8 +3,8 @@ package forge.gui.match.controllers;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import forge.AllZone;
import forge.Command; import forge.Command;
import forge.game.GameState;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SDisplayUtil;
@@ -33,7 +33,10 @@ public enum CStack implements ICDoc, Observer {
*/ */
@Override @Override
public void initialize() { public void initialize() {
AllZone.getStack().addObserver(this); }
public void subscribe(GameState currentGame) {
currentGame.getStack().addObserver(this);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -30,5 +30,4 @@ public class CEmptyDoc implements ICDoc {
@Override @Override
public void update() { public void update() {
} }
} }

View File

@@ -33,7 +33,6 @@ import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder; import javax.swing.border.MatteBorder;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.AllZone;
import forge.card.cardfactory.CardFactoryUtil; import forge.card.cardfactory.CardFactoryUtil;
import forge.card.mana.ManaPool; import forge.card.mana.ManaPool;
import forge.game.player.Player; import forge.game.player.Player;
@@ -122,8 +121,7 @@ public class VField implements IVDoc {
// TODO player is hard-coded into tabletop...should be dynamic // TODO player is hard-coded into tabletop...should be dynamic
// (haven't looked into it too deeply). Doublestrike 12-04-12 // (haven't looked into it too deeply). Doublestrike 12-04-12
tabletop = new PlayArea(scroller, tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1 );
AllZone.getComputerPlayer().equals(player) ? true : false);
control = new CField(player, this); control = new CField(player, this);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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 <i>as a whole</i> - 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<GameSummary> gamesPlayed = new ArrayList<GameSummary>();
private final List<CardPrinted> antesWon = new ArrayList<CardPrinted>();
private final List<CardPrinted> antesLost = new ArrayList<CardPrinted>();
// ArrayList<GameSpecialConditions>
/**
* 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<GameSummary> 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<String, Integer> winsCount = new HashMap<String, Integer>();
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<Card> 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<CardPrinted> addAnteWon(final List<Card> antes) {
List<CardPrinted> antesPrinted = new ArrayList<CardPrinted>();
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<CardPrinted> 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<Card> 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<CardPrinted> addAnteLost(final List<Card> antes) {
List<CardPrinted> antesPrinted = new ArrayList<CardPrinted>();
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;
}
}

View File

@@ -38,11 +38,8 @@ import forge.control.input.InputControl;
import forge.deck.CardCollections; import forge.deck.CardCollections;
import forge.error.ExceptionHandler; import forge.error.ExceptionHandler;
import forge.game.GameState; import forge.game.GameState;
import forge.game.GameSummary; import forge.game.MatchController;
import forge.game.player.ComputerAIGeneral; import forge.game.player.LobbyPlayer;
import forge.game.player.ComputerAIInput;
import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletData;
import forge.properties.ForgePreferences; import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
@@ -50,7 +47,6 @@ import forge.properties.ForgeProps;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.data.QuestPreferences; import forge.quest.data.QuestPreferences;
import forge.util.Aggregates;
import forge.util.FileUtil; import forge.util.FileUtil;
import forge.util.HttpUtil; import forge.util.HttpUtil;
import forge.util.IStorageView; import forge.util.IStorageView;
@@ -80,11 +76,11 @@ public enum FModel {
private final GameAction gameAction; private final GameAction gameAction;
private final QuestPreferences questPreferences; private final QuestPreferences questPreferences;
private final ForgePreferences preferences; private final ForgePreferences preferences;
private final GameState gameState; private GameState gameState;
private final FMatchState matchState;
private GauntletData gauntletData; private GauntletData gauntletData;
private QuestController quest = null; private QuestController quest = null;
private final MatchController match;
private final EditionCollection editions; private final EditionCollection editions;
private final FormatCollection formats; private final FormatCollection formats;
@@ -133,8 +129,6 @@ public enum FModel {
} }
this.gameAction = new GameAction(); this.gameAction = new GameAction();
this.gameState = new GameState();
this.matchState = new FMatchState();
this.questPreferences = new QuestPreferences(); this.questPreferences = new QuestPreferences();
this.gauntletData = new GauntletData(); this.gauntletData = new GauntletData();
@@ -146,13 +140,12 @@ public enum FModel {
this.blocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/blocks.txt", editions)); this.blocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/blocks.txt", editions));
this.fantasyBlocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/fantasyblocks.txt", editions)); this.fantasyBlocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/fantasyblocks.txt", editions));
this.match = new MatchController();
// TODO - there's got to be a better place for this...oblivion? // TODO - there's got to be a better place for this...oblivion?
Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED);
// Instantiate AI // Instantiate AI
AllZone.setInputControl(new InputControl(FModel.this)); 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 /// Wrong direction here. It is computer that lives inside player, not a player in computer
testNetworkConnection(); testNetworkConnection();
@@ -360,25 +353,6 @@ public enum FModel {
return this.gameState; 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. * TODO: Write javadoc for this method.
* *
@@ -444,4 +418,17 @@ public enum FModel {
public void setGauntletData(GauntletData data0) { public void setGauntletData(GauntletData data0) {
this.gauntletData = data0; this.gauntletData = data0;
} }
public MatchController getMatch() {
return match;
}
/**
* TODO: Write javadoc for this method.
* @param players
*/
public GameState newGame(Iterable<LobbyPlayer> players) {
gameState = new GameState(players);
return gameState;
}
} }

View File

@@ -84,9 +84,6 @@ public final class QuestUtilCards {
return pool; return pool;
} }
// adds 11 cards, to the current card pool
// (I chose 11 cards instead of 15 in order to make things more challenging)
/** /**
* <p> * <p>
* addCards. * addCards.
@@ -261,6 +258,10 @@ public final class QuestUtilCards {
this.sellCard(card, price, true); this.sellCard(card, price, true);
} }
public void loseCard(final CardPrinted card) {
this.sellCard(card, 0, false);
}
/** /**
* Sell card. * Sell card.
* *
@@ -271,7 +272,7 @@ public final class QuestUtilCards {
* @param addToShop * @param addToShop
* true if this card should be added to the shop, false otherwise * 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) { if (price > 0) {
this.qa.setCredits(this.qa.getCredits() + price); this.qa.setCredits(this.qa.getCredits() + price);
} }

View File

@@ -22,7 +22,6 @@ import forge.gui.deckeditor.VDeckEditorUI;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.SLayoutConstants; import forge.gui.framework.SLayoutConstants;
import forge.gui.home.CHomeUI;
import forge.gui.home.VHomeUI; import forge.gui.home.VHomeUI;
import forge.gui.match.TargetingOverlay; import forge.gui.match.TargetingOverlay;
import forge.gui.match.VMatchUI; import forge.gui.match.VMatchUI;