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/FControl.java -text
src/main/java/forge/control/KeyboardShortcuts.java -text
src/main/java/forge/control/Lobby.java -text
src/main/java/forge/control/RestartUtil.java -text
src/main/java/forge/control/bazaar/ControlStall.java -text
src/main/java/forge/control/bazaar/package-info.java svneol=native#text/plain
@@ -12626,11 +12627,12 @@ src/main/java/forge/game/GameEndReason.java -text
src/main/java/forge/game/GameFormat.java -text
src/main/java/forge/game/GameLossReason.java -text
src/main/java/forge/game/GameNew.java -text
src/main/java/forge/game/GamePlayerRating.java -text
src/main/java/forge/game/GameOutcome.java -text
src/main/java/forge/game/GameState.java -text
src/main/java/forge/game/GameSummary.java svneol=native#text/plain
src/main/java/forge/game/GameType.java -text
src/main/java/forge/game/PlayerStartsGame.java -text
src/main/java/forge/game/MatchController.java -text
src/main/java/forge/game/MatchStartHelper.java -text
src/main/java/forge/game/PlayerStartConditions.java -text
src/main/java/forge/game/limited/BoosterDeck.java -text
src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain
src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain
@@ -12670,7 +12672,10 @@ src/main/java/forge/game/player/ComputerUtil.java svneol=native#text/plain
src/main/java/forge/game/player/ComputerUtilAttack.java svneol=native#text/plain
src/main/java/forge/game/player/ComputerUtilBlock.java svneol=native#text/plain
src/main/java/forge/game/player/HumanPlayer.java svneol=native#text/plain
src/main/java/forge/game/player/LobbyPlayer.java -text
src/main/java/forge/game/player/Player.java svneol=native#text/plain
src/main/java/forge/game/player/PlayerOutcome.java -text
src/main/java/forge/game/player/PlayerStatistics.java -text
src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain
src/main/java/forge/game/player/PlayerUtil.java svneol=native#text/plain
src/main/java/forge/game/player/package-info.java svneol=native#text/plain
@@ -12892,7 +12897,6 @@ src/main/java/forge/item/PreconDeck.java -text
src/main/java/forge/item/TournamentPack.java -text
src/main/java/forge/item/package-info.java -text
src/main/java/forge/model/BuildInfo.java -text
src/main/java/forge/model/FMatchState.java svneol=native#text/plain
src/main/java/forge/model/FModel.java svneol=native#text/plain
src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
src/main/java/forge/model/package-info.java svneol=native#text/plain

View File

@@ -17,8 +17,6 @@
*/
package forge;
import java.util.List;
import forge.card.cardfactory.CardFactory;
import forge.card.cardfactory.CardFactoryInterface;
import forge.card.replacement.ReplacementHandler;
@@ -29,13 +27,11 @@ import forge.game.limited.GauntletMini;
import forge.game.phase.Combat;
import forge.game.phase.EndOfTurn;
import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.game.zone.MagicStack;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import forge.util.Aggregates;
/**
@@ -75,40 +71,6 @@ public final class AllZone {
// shared between Input_Attack, Input_Block, Input_CombatDamage ,
// InputState_Computer
/**
* <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>
* getGauntletData.

View File

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

View File

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

View File

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

View File

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

View File

@@ -35,6 +35,7 @@ import forge.AllZone;
import forge.Singletons;
import forge.control.KeyboardShortcuts.Shortcut;
import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.VDeckEditorUI;
import forge.gui.framework.SOverflowUtil;
@@ -49,6 +50,7 @@ import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.QuestDataIO;
import forge.util.Aggregates;
import forge.view.FView;
/**
@@ -273,6 +275,20 @@ public enum FControl {
/** @return {@link forge.game.player.Player} */
public Player getPlayer() {
return AllZone.getHumanPlayer();
if (Singletons.getModel() == null)
return null;
return Aggregates.firstFieldEquals(Singletons.getModel().getGameState().getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.HUMAN);
}
/**
* TODO: Write javadoc for this method.
* @return
*/
private Lobby lobby = null;
public Lobby getLobby() {
if( lobby == null )
lobby = new Lobby();
return lobby;
}
}

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,7 +19,6 @@ package forge.control.input;
import java.util.List;
import forge.AllZone;
import forge.Card;
import forge.CardLists;
@@ -77,7 +76,7 @@ public class InputPayReturnCost extends Input {
this.ability = sa;
this.returnCost = cost;
this.choiceList = CardLists.getValidCards(AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), AllZone.getHumanPlayer(), source);
this.choiceList = CardLists.getValidCards(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), Singletons.getControl().getPlayer(), source);
String amountString = cost.getAmount();
this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
: CardFactoryUtil.xCount(source, source.getSVar(amountString));

View File

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

View File

@@ -21,10 +21,6 @@ package forge.game;
* The Enum GameLossReason.
*/
public enum GameLossReason {
/** The Did not lose yet. */
DidNotLoseYet, // a winner must have this status by the end of the game
/** The Conceded. */
Conceded, // rule 104.3a
/** The Life reached zero. */
@@ -36,7 +32,9 @@ public enum GameLossReason {
// 104.3e and others
/** The Spell effect. */
SpellEffect
SpellEffect,
OpponentWon
/*
* DoorToNothingness, // Door To Nothingness's ability activated

View File

@@ -19,21 +19,12 @@ import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.CardUtil;
import forge.Constant.Preferences;
import forge.Singletons;
import forge.control.FControl;
import forge.control.input.InputMulligan;
import forge.deck.Deck;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil;
import forge.gui.match.CMatchUI;
import forge.gui.match.VMatchUI;
import forge.gui.match.controllers.CMessage;
import forge.gui.match.nonsingleton.VField;
import forge.gui.match.views.VAntes;
import forge.gui.toolbox.FLabel;
import forge.item.CardPrinted;
import forge.properties.ForgePreferences.FPref;
import forge.util.Aggregates;
@@ -44,6 +35,63 @@ import forge.util.MyRandom;
* All of these methods can and should be static.
*/
public class GameNew {
private static void prepareSingleLibrary(final Player player, final Deck deck, final Map<Player, List<String>> removedAnteCards, final List<String> rAICards) {
final Random generator = MyRandom.getRandom();
boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE);
final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL)
&& Singletons.getModel().getMatch().getGameType() == GameType.Constructed;
PlayerZone library = player.getZone(ZoneType.Library);
for (final Entry<CardPrinted, Integer> stackOfCards : deck.getMain()) {
final CardPrinted cardPrinted = stackOfCards.getKey();
for (int i = 0; i < stackOfCards.getValue(); i++) {
final Card card = cardPrinted.toForgeCard(player);
// apply random pictures for cards
if ( player.isComputer() ) {
final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount();
if (cntVariants > 1) {
card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1);
card.setImageFilename(CardUtil.buildFilename(card));
}
}
// Assign random foiling on approximately 1:20 cards
if (cardPrinted.isFoil() || (canRandomFoil && MyRandom.percentTrue(5))) {
final int iFoil = MyRandom.getRandom().nextInt(9) + 1;
card.setFoil(iFoil);
}
if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) {
if(!removedAnteCards.containsKey(player))
removedAnteCards.put(player, new ArrayList<String>());
removedAnteCards.get(player).add(card.getName());
} else {
library.add(card);
}
// mark card as difficult for AI to play
if ( player.isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) {
rAICards.add(card.getName());
// get card picture so that it is in the image cache
// ImageCache.getImage(card);
}
}
}
// Shuffling
// Ai may cheat
if ( player.isComputer() && Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_SMOOTH_LAND) ) {
// do this instead of shuffling Computer's deck
final Iterable<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.
@@ -51,30 +99,27 @@ public class GameNew {
* TODO: Accept something like match state as parameter. Match should be aware of players,
* their decks and other special starting conditions.
*/
public static void newGame(final PlayerStartsGame... players) {
Singletons.getControl().changeState(FControl.MATCH_SCREEN);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
public static void newGame(final Map<Player, PlayerStartConditions> playersConditions) {
AllZone.getInputControl().clearInput();
AllZone.getColorChanger().reset();
// Update observers
AllZone.getStack().updateObservers();
AllZone.getInputControl().updateObservers();
AllZone.getGameLog().updateObservers();
newGameCleanup();
newMatchCleanup();
Singletons.getModel().getPreferences().actuateMatchPreferences();
Card.resetUniqueNumber();
// need this code here, otherwise observables fail
forge.card.trigger.Trigger.resetIDs();
AllZone.getTriggerHandler().clearTriggerSettings();
AllZone.getTriggerHandler().clearDelayedTrigger();
for( PlayerStartsGame p : players ) {
final Player player = p.getPlayer();
player.setStartingLife(p.initialLives);
// 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?
player.updateObservers();
player.setDeck(p.getDeck());
PlayerZone bf = player.getZone(ZoneType.Battlefield);
if (p.cardsOnBattlefield != null) {
for (final Card c : p.cardsOnBattlefield) {
if (p.getValue().getCardsOnTable() != null) {
for (final Card c : p.getValue().getCardsOnTable()) {
c.addController(player);
c.setOwner(player);
bf.add(c, false);
@@ -83,77 +128,14 @@ public class GameNew {
c.refreshUniqueNumber();
}
}
prepareSingleLibrary(player, p.getValue().getDeck(), removedAnteCards, rAICards);
player.updateObservers();
bf.updateObservers();
p.getPlayer().getZone(ZoneType.Hand).updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
}
GameNew.actuateGame(players);
}
/**
* This must be separated from the newGame method since life totals and
* player details could be adjusted before the game is started.
*
* That process (also cleanup and observer updates) should be done in
* newGame, then when all is ready, call this function.
*/
private static void actuateGame(final PlayerStartsGame... players) {
forge.card.trigger.Trigger.resetIDs();
AllZone.getTriggerHandler().clearTriggerSettings();
AllZone.getTriggerHandler().clearDelayedTrigger();
CMessage.SINGLETON_INSTANCE.updateGameInfo();
// friendliness
final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL)
&& Singletons.getModel().getMatchState().getGameType().equals(GameType.Constructed);
final Random generator = MyRandom.getRandom();
boolean useAnte = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_ANTE);
final Map<Player, List<String>> removedAnteCards = new HashMap<Player, List<String>>();
final List<String> rAICards = new ArrayList<String>();
// Create Card libraries out of decks (CardPrinted)
for( PlayerStartsGame p : players )
{
PlayerZone library = p.getPlayer().getZone(ZoneType.Library);
for (final Entry<CardPrinted, Integer> stackOfCards : p.getDeck().getMain()) {
final CardPrinted cardPrinted = stackOfCards.getKey();
for (int i = 0; i < stackOfCards.getValue(); i++) {
final Card card = cardPrinted.toForgeCard(p.getPlayer());
// apply random pictures for cards
if ( p.getPlayer().isComputer() ) {
final int cntVariants = cardPrinted.getCard().getEditionInfo(cardPrinted.getEdition()).getCopiesCount();
if (cntVariants > 1) {
card.setRandomPicture(generator.nextInt(cntVariants - 1) + 1);
card.setImageFilename(CardUtil.buildFilename(card));
}
}
// Assign random foiling on approximately 1:20 cards
if (cardPrinted.isFoil() || (canRandomFoil && MyRandom.percentTrue(5))) {
final int iFoil = MyRandom.getRandom().nextInt(9) + 1;
card.setFoil(iFoil);
}
if (!useAnte && card.hasKeyword("Remove CARDNAME from your deck before playing if you're not playing for ante.")) {
if(!removedAnteCards.containsKey(p.getPlayer()))
removedAnteCards.put(p.getPlayer(), new ArrayList<String>());
removedAnteCards.get(p.getPlayer()).add(card.getName());
} else {
library.add(card);
}
// mark card as difficult for AI to play
if ( p.getPlayer().isComputer() && card.getSVar("RemAIDeck").equals("True") && !rAICards.contains(card.getName())) {
rAICards.add(card.getName());
// get card picture so that it is in the image cache
// ImageCache.getImage(card);
}
}
}
}
if (rAICards.size() > 0) {
String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards);
@@ -168,33 +150,17 @@ public class GameNew {
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
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
if (Singletons.getModel().getMatchState().getGamesPlayedCount() == 0) {
if (Singletons.getModel().getMatch().getPlayedGames().isEmpty()) {
GameNew.seeWhoPlaysFirstDice();
} else if (Singletons.getModel().getMatchState().hasWonLastGame(AllZone.getHumanPlayer().getName())) {
// if player won last, AI starts
GameNew.computerPlayOrDraw("Computer lost the last game.");
} else {
GameNew.humanPlayOrDraw("Human lost the last game.");
Player human = Singletons.getControl().getPlayer();
Player goesFirst = Singletons.getModel().getMatch().getLastGameOutcome().isWinner(human.getLobbyPlayer()) ? human.getOpponent() : human;
setPlayersFirstTurn(goesFirst);
}
// Draw 7 cards
for (final Player p : Singletons.getModel().getGameState().getPlayers())
{
@@ -235,9 +200,6 @@ public class GameNew {
p.drawCard();
}
}
CMatchUI.SINGLETON_INSTANCE.setCard(AllZone.getHumanPlayer().getCardsIn(ZoneType.Hand).get(0));
AllZone.getInputControl().setInput(new InputMulligan());
} // newGame()
private static String buildFourColumnList(String firstLine, List<String> cAnteRemoved ) {
@@ -254,52 +216,6 @@ public class GameNew {
return sb.toString();
}
private static void newGameCleanup() {
final GameState gs = Singletons.getModel().getGameState();
gs.setGameSummary(new GameSummary(Iterables.transform(gs.getPlayers(), Player.Accessors.FN_GET_NAME)));
gs.getPhaseHandler().reset();
gs.getStack().reset();
gs.getCombat().reset();
gs.getEndOfTurn().reset();
gs.getEndOfCombat().reset();
gs.getUntap().reset();
gs.getUpkeep().reset();
gs.getGameLog().reset();
gs.setGameOver(false);
for (final Player p : gs.getPlayers()) {
p.reset();
for (final ZoneType z : Player.ALL_ZONES) {
p.getZone(z).reset();
}
}
gs.getStaticEffects().reset();
AllZone.getInputControl().clearInput();
AllZone.getColorChanger().reset();
}
private static void newMatchCleanup() {
if (Singletons.getModel().getMatchState().getGamesPlayedCount() != 0) { return; }
// TODO restore this functionality!!!
//VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getDocument().setVisible(Preferences.DEV_MODE);
final List<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
// changes AllZone.getComputerPlayer().getZone(Zone.Library)
@@ -371,48 +287,34 @@ public class GameNew {
computerDie = MyRandom.getRandom().nextInt(20);
}
if (playerDie > computerDie) {
humanPlayOrDraw(dieRollMessage(playerDie, computerDie));
}
else {
computerPlayOrDraw(dieRollMessage(playerDie, computerDie));
List<Player> allPlayers = Singletons.getModel().getGameState().getPlayers();
setPlayersFirstTurn(allPlayers.get(MyRandom.getRandom().nextInt(allPlayers.size())));
}
private static void setPlayersFirstTurn(Player goesFirst)
{
String message = goesFirst + " has won the coin toss.";
if ( goesFirst.isHuman() ) {
if( !humanPlayOrDraw(message) );
} else {
computerPlayOrDraw(message);
}
Singletons.getModel().getGameState().getPhaseHandler().setPlayerTurn(goesFirst);
} // seeWhoPlaysFirstDice()
private static void computerStartsGame() {
final Player computer = AllZone.getComputerPlayer();
Singletons.getModel().getGameState().getPhaseHandler().setPlayerTurn(computer);
// AllZone.getGameInfo().setPlayerWhoGotFirstTurn(computer.getName());
}
private static String dieRollMessage(int playerDie, int computerDie) {
StringBuilder sb = new StringBuilder();
sb.append("Human has rolled a: ");
sb.append(playerDie);
sb.append(". ");
sb.append("Computer has rolled a: ");
sb.append(computerDie);
sb.append(".");
return sb.toString();
}
private static void humanPlayOrDraw(String message) {
private static boolean humanPlayOrDraw(String message) {
final Object[] possibleValues = { "Play", "Draw" };
final Object playDraw = JOptionPane.showOptionDialog(null, message + "\n\nWould you like to play or draw?",
"Play or Draw?", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
possibleValues, possibleValues[0]);
if (playDraw.equals(1)) {
computerStartsGame();
}
return !playDraw.equals(1);
}
private static void computerPlayOrDraw(String message) {
JOptionPane.showMessageDialog(null, message + "\nComputer Going First",
"Play or Draw?", JOptionPane.INFORMATION_MESSAGE);
computerStartsGame();
}
}

View File

@@ -19,7 +19,13 @@ package forge.game;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerStatistics;
/**
* <p>
@@ -27,16 +33,14 @@ import java.util.Map;
* </p>
*
* @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
// only getters) and
// 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. */
// private String playerGotFirstTurn = "Nobody";
@@ -44,14 +48,10 @@ public final class GameSummary {
/** The last turn number. */
private int lastTurnNumber = 0;
/** The win condition. */
private GameEndReason winCondition;
/** The spell effect win. */
private String spellEffectWin;
/** The player rating. */
private final Map<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.
@@ -59,31 +59,17 @@ public final class GameSummary {
* @param names
* the names
*/
public GameSummary(final String... names) {
this(Arrays.asList(names));
public GameOutcome(GameEndReason reason, final Player... names) {
this(reason, Arrays.asList(names));
}
public GameSummary(final Iterable<String> list) {
for (final String n : list) {
this.playerRating.put(n, new GamePlayerRating());
public GameOutcome(GameEndReason reason, final Iterable<Player> list) {
winCondition = reason;
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.
@@ -91,7 +77,12 @@ public final class GameSummary {
* @return true, if is draw
*/
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
* @return true, if is winner
*/
public boolean isWinner(final String name) {
return (name != null) && name.equals(this.playerWinner);
public boolean isWinner(final LobbyPlayer who) {
PlayerStatistics stats = playerRating.get(who);
return stats.getOutcome().hasWon();
}
/**
@@ -110,8 +102,13 @@ public final class GameSummary {
*
* @return the winner
*/
public String getWinner() {
return this.playerWinner;
public LobbyPlayer getWinner() {
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
* @return the player rating
*/
public GamePlayerRating getPlayerRating(final String name) {
public PlayerStatistics getStatistics(final LobbyPlayer name) {
return this.playerRating.get(name);
}
@@ -152,20 +149,26 @@ public final class GameSummary {
* this.playerGotFirstTurn = playerName; }
*/
/**
* Notify next turn.
*/
public void notifyNextTurn() {
this.lastTurnNumber++;
}
/**
* Gets the win spell effect.
*
* @return the win spell effect
*/
public String getWinSpellEffect() {
return this.spellEffectWin;
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.Untap;
import forge.game.phase.Upkeep;
import forge.game.player.AIPlayer;
import forge.game.player.HumanPlayer;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.MagicStack;
@@ -51,14 +50,13 @@ public class GameState {
/** The Constant AI_PLAYER_NAME. */
public static final String AI_PLAYER_NAME = "Computer";
private final List<Player> players = new ArrayList<Player>();
private final List<Player> roPlayers;
private final Cleanup cleanup = new Cleanup();
private final EndOfTurn endOfTurn = new EndOfTurn();
private final EndOfCombat endOfCombat = new EndOfCombat();
private final Untap untap = new Untap();
private final Upkeep upkeep = new Upkeep();
private final PhaseHandler phaseHandler = new PhaseHandler();
private PhaseHandler phaseHandler = new PhaseHandler();
private final MagicStack stack = new MagicStack();
private final StaticEffects staticEffects = new StaticEffects();
private final TriggerHandler triggerHandler = new TriggerHandler();
@@ -70,15 +68,17 @@ public class GameState {
private final PlayerZone stackZone = new PlayerZone(ZoneType.Stack, null);
private long timestamp = 0;
private GameSummary gameSummary;
private int nTurn = 0;
/**
* Constructor.
* @param players2
*/
public GameState() { /* no more zones to map here */
players.add(new HumanPlayer(GameState.HUMAN_PLAYER_NAME));
players.add(new AIPlayer(GameState.AI_PLAYER_NAME));
public GameState(Iterable<LobbyPlayer> players2) { /* no more zones to map here */
List<Player> players = new ArrayList<Player>();
for(LobbyPlayer p : players2) {
players.add(p.getIngamePlayer());
}
roPlayers = Collections.unmodifiableList(players);
}
@@ -238,23 +238,6 @@ public class GameState {
this.timestamp = timestamp0;
}
/**
* Gets the game info.
*
* @return the game info
*/
public final GameSummary getGameSummary() {
return this.gameSummary;
}
/**
* Sets the game info.
*
* @param summary0 {@link forge.game.GameSummary}
*/
public final void setGameSummary(final GameSummary summary0) {
this.gameSummary = summary0;
}
/**
* @return the replacementHandler
@@ -273,8 +256,25 @@ public class GameState {
/**
* @param go the gameOver to set
*/
public void setGameOver(boolean go) {
this.gameOver = go;
public void setGameOver() {
this.gameOver = true;
for(Player p : roPlayers) {
p.onGameOver();
}
}
/**
* TODO: Write javadoc for this method.
* @return
*/
public int getTurnNumber() {
return nTurn;
}
/**
* TODO: Write javadoc for this method.
*/
public void notifyNextTurn() {
nTurn++;
}
}

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.SwingWorker;
import java.util.List;
import forge.AllZone;
import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck;
import forge.game.GameNew;
import forge.game.GameType;
import forge.game.PlayerStartsGame;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType;
import forge.gui.SOverlayUtils;
import forge.gui.match.CMatchUI;
/**
* <p>
@@ -158,10 +159,15 @@ public class GauntletMini {
@Override
public Object doInBackground() {
CMatchUI.SINGLETON_INSTANCE.initMatch(null);
Singletons.getModel().getMatchState().setGameType(gauntletType);
GameNew.newGame( new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDecks.get(currentRound)));
MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck);
starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDecks.get(currentRound));
MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(gauntletType, starter.getPlayerMap());
mc.startRound();
return null;
}

View File

@@ -382,7 +382,7 @@ public class CombatUtil {
*/
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();
// 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.List;
import java.util.Observer;
import java.util.Stack;
import com.esotericsoftware.minlog.Log;
@@ -53,27 +52,39 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
private static final long serialVersionUID = 5207222278370963197L;
private int phaseIndex;
private int turn;
// Please use getX, setX, and incrementX methods instead of directly
// accessing the following:
/** Constant <code>GameBegins=0</code>. */
private static int gameBegins = 0;
private int phaseIndex = 0;
private int turn = 1;
private final Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
private int extraCombats;
private int extraCombats = 0;
private int nCombatsThisTurn;
private boolean bPreventCombatDamageThisTurn;
private int nCombatsThisTurn = 0;
private boolean bPreventCombatDamageThisTurn = false;
private Player playerTurn = AllZone.getHumanPlayer();
private Player playerTurn = null;
private Player skipToTurn = AllZone.getHumanPlayer();
private Player skipToTurn = null;
private PhaseType skipToPhase = PhaseType.CLEANUP;
private boolean autoPass = false;
// priority player
private Player pPlayerPriority = null;
private Player pFirstPriority = null;
private boolean bPhaseEffects = true;
private boolean bSkipPhase = true;
private boolean bCombat = false;
private boolean bRepeat = false;
/** The need to next phase. */
private boolean needToNextPhase = false;
// This should only be true four times! that is for the initial nextPhases
// in MyObservable
/** The need to next phase init. */
private int needToNextPhaseInit = 0;
/**
* <p>
* isPlayerTurn.
@@ -112,8 +123,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
// priority player
private Player pPlayerPriority = AllZone.getHumanPlayer();
/**
* <p>
* getPriorityPlayer.
@@ -137,8 +146,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.pPlayerPriority = p;
}
private Player pFirstPriority = AllZone.getHumanPlayer();
/**
* <p>
* getFirstPriority.
@@ -188,8 +195,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.setPriority(this.playerTurn);
}
private boolean bPhaseEffects = true;
/**
* <p>
* doPhaseEffects.
@@ -213,8 +218,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bPhaseEffects = b;
}
private boolean bSkipPhase = true;
/**
* <p>
* doSkipPhase.
@@ -238,8 +241,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bSkipPhase = b;
}
private boolean bCombat = false;
/**
* <p>
* inCombat.
@@ -263,8 +264,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.bCombat = b;
}
private boolean bRepeat = false;
/**
* <p>
* repeatPhase.
@@ -274,38 +273,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
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>
* 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>
* Setter for the field <code>needToNextPhase</code>.
@@ -934,11 +892,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
return this.needToNextPhase;
}
// This should only be true four times! that is for the initial nextPhases
// in MyObservable
/** The need to next phase init. */
private int needToNextPhaseInit = 0;
/**
* <p>
* isNeedToNextPhaseInit.
@@ -998,31 +951,6 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
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
// devSetupGameState code
// 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 Player turn = ph.getPlayerTurn();
Singletons.getModel().getGameSummary().notifyNextTurn();
CMessage.SINGLETON_INSTANCE.updateGameInfo();
Singletons.getModel().getGameState().notifyNextTurn();
CMessage.SINGLETON_INSTANCE.updateGameInfo(Singletons.getModel().getMatch());
AllZone.getCombat().reset();
AllZone.getCombat().setAttackingPlayer(turn);

View File

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

View File

@@ -29,6 +29,8 @@ import forge.control.input.Input;
import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI;
import forge.quest.QuestController;
import forge.quest.bazaar.QuestItemType;
/**
* <p>
@@ -48,24 +50,8 @@ public class HumanPlayer extends Player {
* @param myName
* a {@link java.lang.String} object.
*/
public HumanPlayer(final String myName) {
this(myName, 20, 0);
}
/**
* <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);
public HumanPlayer(final LobbyPlayer player) {
super(player);
}
// //////////////
@@ -222,4 +208,15 @@ public class HumanPlayer extends Player {
return PlayerType.HUMAN;
}
@Override
public final int doMulligan() {
int newHand = super.doMulligan();
final QuestController quest = Singletons.getModel().getQuest();
if (quest.isLoaded() && quest.getAssets().hasItem(QuestItemType.SLEIGHT) && (getStats().getMulliganCount() == 1)) {
drawCard();
newHand++;
getStats().notifyOpeningHandSize(newHand);
}
return newHand;
}
} // end HumanPlayer class

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.staticability.StaticAbility;
import forge.card.trigger.TriggerType;
import forge.deck.Deck;
import forge.game.GameLossReason;
import forge.game.phase.PhaseHandler;
import forge.game.zone.PlayerZone;
@@ -69,15 +68,15 @@ import forge.util.MyRandom;
* @author Forge
* @version $Id$
*/
public abstract class Player extends GameEntity implements Comparable<Player> {
public abstract class Player extends GameEntity implements Comparable<Player> {
/** The poison counters. */
private int poisonCounters;
private int poisonCounters = 0;
/** The life. */
private int life;
private int life = 20;
/** The life this player started the game with. */
private int startingLife;
private int startingLife = 20;
/** The assigned damage. */
private final Map<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. */
private int numPowerSurgeLands;
/** The alt win. */
private boolean altWin = false;
/** The alt win source name. */
private String altWinSourceName;
/** The alt lose. */
// private boolean altLose = false;
/** The loss state. */
private GameLossReason lossState = GameLossReason.DidNotLoseYet;
/** The lose condition spell. */
private String loseConditionSpell;
/** The n turns. */
private int nTurns = 0;
/** The skip next untap. */
private boolean skipNextUntap = false;
@@ -122,7 +103,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
private int maxHandSize = 7;
/** The last drawn card. */
private Card lastDrawnCard;
private Card lastDrawnCard = null;
/** The num drawn this turn. */
private int numDrawnThisTurn = 0;
@@ -134,7 +115,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
private ArrayList<String> keywords = new ArrayList<String>();
/** The mana pool. */
private ManaPool manaPool = null;
private ManaPool manaPool = new ManaPool(this);
/** The must attack entity. */
private Object mustAttackEntity = null;
@@ -148,24 +129,19 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
/** The zones. */
private final Map<ZoneType, PlayerZone> zones = new EnumMap<ZoneType, PlayerZone>(ZoneType.class);
private PlayerStatistics stats = new PlayerStatistics();
/** The Constant ALL_ZONES. */
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>
* Constructor for Player.
* </p>
*
* @param myName
* a {@link java.lang.String} object.
*/
public Player(final String myName) {
this(myName, 20, 0);
private LobbyPlayer lobbyPlayer;
public final PlayerOutcome getOutcome() {
return stats.getOutcome();
}
/**
@@ -180,48 +156,19 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @param myPoisonCounters
* a int.
*/
public Player(final String myName, final int myLife, final int myPoisonCounters) {
public Player(LobbyPlayer lobbyPlayer0) {
lobbyPlayer = lobbyPlayer0;
for (final ZoneType z : Player.ALL_ZONES) {
final PlayerZone toPut = z == ZoneType.Battlefield ? new PlayerZoneBattlefield(z, this)
final PlayerZone toPut = z == ZoneType.Battlefield
? new PlayerZoneBattlefield(z, this)
: new PlayerZone(z, this);
this.zones.put(z, toPut);
}
this.reset();
this.setName(myName);
this.life = myLife;
this.poisonCounters = myPoisonCounters;
this.setName(lobbyPlayer.getName());
}
/**
* <p>
* 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();
public final PlayerStatistics getStats() {
return stats;
}
/**
@@ -1267,6 +1214,32 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
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>
* 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);
c.setDrawnThisTurn(true);
this.numDrawnThisTurn++;
@@ -1441,7 +1414,9 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return the all cards
*/
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.
*/
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>
*/
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
/**
* <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>
* altWinConditionMet.
@@ -2171,8 +2104,8 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
System.out.println("Tried to win, but currently can't.");
return;
}
this.altWin = true;
this.altWinSourceName = sourceName;
this.setOutcome(PlayerOutcome.altWin(sourceName));
}
/**
@@ -2187,22 +2120,23 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return a boolean.
*/
public final boolean loseConditionMet(final GameLossReason state, final String spellName) {
if (this.cantLose()) {
System.out.println("Tried to lose, but currently can't.");
return false;
if ( state != GameLossReason.OpponentWon ) {
if (this.cantLose()) {
System.out.println("Tried to lose, but currently can't.");
return false;
}
// Replacement effects
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Affected", this);
runParams.put("Event", "GameLoss");
if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) {
return false;
}
}
// Replacement effects
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Affected", this);
runParams.put("Event", "GameLoss");
if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) {
return false;
}
this.lossState = state;
this.loseConditionSpell = spellName;
setOutcome(PlayerOutcome.loss(state, spellName));
return true;
}
@@ -2210,8 +2144,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* Concede.
*/
public final void concede() { // No cantLose checks - just lose
this.lossState = GameLossReason.Conceded;
this.loseConditionSpell = null;
setOutcome(PlayerOutcome.concede());
}
/**
@@ -2222,7 +2155,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @return a boolean.
*/
public final boolean cantLose() {
if (this.lossState == GameLossReason.Conceded) {
if (this.getOutcome() != null && this.getOutcome().lossState == GameLossReason.Conceded) {
return false;
}
@@ -2258,11 +2191,10 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
*
* @return a boolean.
*/
public final boolean hasLost() {
public final boolean checkLoseCondition() {
if (this.lossState != GameLossReason.DidNotLoseYet) {
return this.loseConditionMet(this.lossState, null);
}
if ( this.getOutcome() != null )
return this.getOutcome().lossState != null;
if (this.poisonCounters >= 10) {
return this.loseConditionMet(GameLossReason.Poisoned, null);
@@ -2287,8 +2219,10 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
if (this.cantWin()) {
return false;
}
// in multiplayer game one player's win is replaced by all other's lose (rule 103.4h)
// so if someone cannot lose, the game appears to continue
return this.altWin;
return this.getOutcome() != null && this.getOutcome().lossState == null;
}
/**
@@ -2714,16 +2648,15 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
return (41 * (41 + this.getName().hashCode()));
}
public Deck getDeck() {
return deck;
}
public void setDeck(Deck deck) {
this.deck = deck;
}
public static class Predicates {
public static final Predicate<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) {
return new Predicate<Player>() {
@Override
@@ -2735,6 +2668,13 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
}
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>(){
@Override
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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.game;
package forge.game.player;
/**
* The Class GamePlayerRating.
*
* @author Max
*/
public class GamePlayerRating {
public class PlayerStatistics {
/** The opening hand size. */
private int openingHandSize = 7;
@@ -30,42 +30,10 @@ public class GamePlayerRating {
/** The times mulliganed. */
private int timesMulliganed = 0;
/** The loss reason. */
private GameLossReason lossReason = GameLossReason.DidNotLoseYet;
private int turnsPlayed = 0;
/** The loss spell name. */
private String lossSpellName;
/**
* Gets the loss reason.
*
* @return the loss reason
*/
public final GameLossReason getLossReason() {
return this.lossReason;
}
/**
* Sets the loss reason.
*
* @param loseCondition
* the lose condition
* @param spellName
* the spell name
*/
public void setLossReason(final GameLossReason loseCondition, final String spellName) {
this.lossReason = loseCondition;
this.lossSpellName = spellName;
}
/**
* Gets the loss spell name.
*
* @return the loss spell name
*/
public String getLossSpellName() {
return this.lossSpellName;
}
private PlayerOutcome outcome;
/**
* Gets the opening hand size.
@@ -102,4 +70,20 @@ public class GamePlayerRating {
this.openingHandSize = newHand;
}
public int getTurnsPlayed() {
return turnsPlayed;
}
public void nextTurn() {
this.turnsPlayed++;
}
public PlayerOutcome getOutcome() {
return outcome;
}
public void setOutcome(PlayerOutcome gameOutcome) {
this.outcome = gameOutcome;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,23 +2,21 @@ package forge.gui.home.multiplayer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.AllZone;
import forge.Command;
import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck;
import forge.deck.DeckgenUtil;
import forge.game.GameNew;
import forge.game.GameType;
import forge.game.PlayerStartsGame;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.gui.match.CMatchUI;
/**
* Controls the deck editor submenu option in the home UI.
@@ -92,13 +90,16 @@ public enum CSubmenuMultiTest implements ICDoc {
Deck humanDeck = DeckgenUtil.getRandomColorDeck(PlayerType.HUMAN);
Deck aiDeck = DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER);
CMatchUI.SINGLETON_INSTANCE.initMatch(numFields, numHands);
Singletons.getModel().getMatchState().setGameType(GameType.Constructed);
MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck);
for( int i = 1; i < numFields; i++ )
starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), aiDeck);
MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(GameType.Constructed, starter.getPlayerMap());
mc.startRound();
if (humanDeck != null && aiDeck != null) {
GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), humanDeck),
new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck));
}
return null;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -37,7 +37,7 @@ public enum CDetail implements ICDoc {
SINGLETON_INSTANCE;
private Card currentCard = null;
private InventoryItem item = null;
//private InventoryItem item = null;
/**
* Shows card details and/or picture in sidebar cardview tabber.
@@ -45,7 +45,7 @@ public enum CDetail implements ICDoc {
* @param c &emsp; Card object
*/
public void showCard(final Card c) {
this.item = null;
//this.item = null;
this.currentCard = c;
VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(c != null && c.isDoubleFaced() ? true : false);
VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(c);
@@ -54,7 +54,7 @@ public enum CDetail implements ICDoc {
public void showCard(InventoryItem item) {
// TODO If we want to display an Items Written Text in the Detail Panel we need to add something into CardDetailPanel
this.item = item;
//this.item = item;
this.currentCard = null;
VDetail.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false);
VDetail.SINGLETON_INSTANCE.getPnlDetail().setCard(null);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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.error.ExceptionHandler;
import forge.game.GameState;
import forge.game.GameSummary;
import forge.game.player.ComputerAIGeneral;
import forge.game.player.ComputerAIInput;
import forge.game.player.Player;
import forge.game.player.PlayerType;
import forge.game.MatchController;
import forge.game.player.LobbyPlayer;
import forge.gauntlet.GauntletData;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
@@ -50,7 +47,6 @@ import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import forge.quest.QuestController;
import forge.quest.data.QuestPreferences;
import forge.util.Aggregates;
import forge.util.FileUtil;
import forge.util.HttpUtil;
import forge.util.IStorageView;
@@ -80,11 +76,11 @@ public enum FModel {
private final GameAction gameAction;
private final QuestPreferences questPreferences;
private final ForgePreferences preferences;
private final GameState gameState;
private final FMatchState matchState;
private GameState gameState;
private GauntletData gauntletData;
private QuestController quest = null;
private final MatchController match;
private final EditionCollection editions;
private final FormatCollection formats;
@@ -133,8 +129,6 @@ public enum FModel {
}
this.gameAction = new GameAction();
this.gameState = new GameState();
this.matchState = new FMatchState();
this.questPreferences = new QuestPreferences();
this.gauntletData = new GauntletData();
@@ -146,13 +140,12 @@ public enum FModel {
this.blocks = new StorageView<CardBlock>(new CardBlock.Reader("res/blockdata/blocks.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?
Preferences.DEV_MODE = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED);
// Instantiate AI
AllZone.setInputControl(new InputControl(FModel.this));
Player computerPlayer = Aggregates.firstFieldEquals(gameState.getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER);
AllZone.getInputControl().setComputer(new ComputerAIInput(new ComputerAIGeneral(computerPlayer)));
/// Wrong direction here. It is computer that lives inside player, not a player in computer
testNetworkConnection();
@@ -360,25 +353,6 @@ public enum FModel {
return this.gameState;
}
/**
* Gets the match state model - that is, the data stored over multiple
* games.
*
* @return {@link forge.model.FMatchState}
*/
public final FMatchState getMatchState() {
return this.matchState;
}
/**
* Gets the game summary.
*
* @return {@link forge.game.GameSummary}
*/
public final GameSummary getGameSummary() {
return this.gameState.getGameSummary();
}
/**
* TODO: Write javadoc for this method.
*
@@ -444,4 +418,17 @@ public enum FModel {
public void setGauntletData(GauntletData data0) {
this.gauntletData = data0;
}
public MatchController getMatch() {
return match;
}
/**
* TODO: Write javadoc for this method.
* @param players
*/
public GameState newGame(Iterable<LobbyPlayer> players) {
gameState = new GameState(players);
return gameState;
}
}

View File

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

View File

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