removed PlayerIndex, players' stats are keyed by name, allowing multiple uniquely-named players

This commit is contained in:
Maxmtg
2011-09-19 09:10:05 +00:00
parent 8c6baf3df9
commit 6bcd32193b
11 changed files with 116 additions and 103 deletions

View File

@@ -55,9 +55,6 @@ public final class AllZone implements NewConstants {
/** Constant <code>inputControl</code>. */
private static final InputControl INPUT_CONTROL = new InputControl(Singletons.getModel());
/** Game state observer <code>gameInfo</code> collects statistics and players' performance. */
private static GameSummary gameInfo = new GameSummary();
/**
* Match State for challenges are stored in a <code>QuestMatchState</code> class instance.
*/
@@ -301,7 +298,7 @@ public final class AllZone implements NewConstants {
* @since 1.0.15
*/
public static GameSummary getGameInfo() {
return gameInfo;
return Singletons.getModel().getGameState().getGameInfo();
}
/**
@@ -439,26 +436,15 @@ public final class AllZone implements NewConstants {
*/
public static void newGameCleanup() {
gameInfo = new GameSummary();
getHumanPlayer().reset();
getComputerPlayer().reset();
getPhase().reset();
getStack().reset();
getCombat().reset();
Singletons.getModel().getGameState().newGameCleanup();
getDisplay().showCombat("");
getDisplay().loadPrefs();
for (Player p : Singletons.getModel().getGameState().getPlayers()) {
for(Zone z : Player.ALL_ZONES) {
p.getZone(z).reset();
}
}
getInputControl().clearInput();
getStaticEffects().reset();
getColorChanger().reset();
// player.reset() now handles this

View File

@@ -22,7 +22,6 @@ import forge.deck.Deck;
import forge.game.GameEndReason;
import forge.game.GameSummary;
import forge.game.GameType;
import forge.game.PlayerIndex;
import forge.gui.GuiUtils;
import forge.gui.input.Input_Mulligan;
import forge.gui.input.Input_PayManaCost;
@@ -598,9 +597,9 @@ public class GameAction {
humanWins = true;
if (human.getAltWin()) {
game.end(GameEndReason.WinsGameSpellEffect, PlayerIndex.HUMAN, human.getWinConditionSource());
game.end(GameEndReason.WinsGameSpellEffect, human.getName(), human.getWinConditionSource());
} else {
game.end(GameEndReason.AllOpponentsLost, PlayerIndex.HUMAN, null);
game.end(GameEndReason.AllOpponentsLost, human.getName(), null);
}
}
@@ -608,14 +607,14 @@ public class GameAction {
if (computer.hasWon() || human.hasLost()) {
if (humanWins) {
// both players won/lost at the same time.
game.end(GameEndReason.Draw, PlayerIndex.DRAW, null);
game.end(GameEndReason.Draw, null, null);
} else {
computerWins = true;
if (computer.getAltWin()) {
game.end(GameEndReason.WinsGameSpellEffect, PlayerIndex.AI, computer.getWinConditionSource());
game.end(GameEndReason.WinsGameSpellEffect, computer.getName(), computer.getWinConditionSource());
} else {
game.end(GameEndReason.AllOpponentsLost, PlayerIndex.AI, null);
game.end(GameEndReason.AllOpponentsLost, computer.getName(), null);
}
}
@@ -623,8 +622,8 @@ public class GameAction {
boolean isGameDone = humanWins || computerWins;
if (isGameDone) {
game.getPlayerRating(PlayerIndex.AI).setLossReason(computer.getLossState(), computer.getLossConditionSource());
game.getPlayerRating(PlayerIndex.HUMAN).setLossReason(human.getLossState(), human.getLossConditionSource());
game.getPlayerRating(computer.getName()).setLossReason(computer.getLossState(), computer.getLossConditionSource());
game.getPlayerRating(human.getName()).setLossReason(human.getLossState(), human.getLossConditionSource());
AllZone.getMatchState().addGamePlayed(game);
}
@@ -1245,7 +1244,7 @@ public class GameAction {
} else {
seeWhoPlaysFirst_CoinToss();
}
} else if (AllZone.getMatchState().hasHumanWonLastGame()) {
} else if (AllZone.getMatchState().hasWonLastGame(AllZone.getHumanPlayer().getName())) {
// if player won last, AI starts
computerStartsGame();
}
@@ -1517,8 +1516,9 @@ public class GameAction {
* <p>computerStartsGame.</p>
*/
public final void computerStartsGame() {
AllZone.getPhase().setPlayerTurn(AllZone.getComputerPlayer());
AllZone.getGameInfo().setPlayerWhoGotFirstTurn(PlayerIndex.AI);
Player computer = AllZone.getComputerPlayer();
AllZone.getPhase().setPlayerTurn(computer);
AllZone.getGameInfo().setPlayerWhoGotFirstTurn(computer.getName());
}
//if Card had the type "Aura" this method would always return true, since local enchantments are always attached to something

View File

@@ -6,7 +6,6 @@ import forge.game.GameFormat;
import forge.game.GameLossReason;
import forge.game.GamePlayerRating;
import forge.game.GameSummary;
import forge.game.PlayerIndex;
import forge.gui.CardListViewer;
import forge.gui.ListChooser;
import forge.item.CardPrinted;
@@ -113,13 +112,14 @@ public class Gui_WinLose extends JFrame implements NewConstants {
restartButton.setEnabled(!isQuestMode); // For quest always disabled, otherwise always on
//show Wins and Loses
int humanWins = model.match.getGamesCountWonByHuman();
int humanLosses = model.match.getGamesCountLostByHuman();
Player human = AllZone.getHumanPlayer();
int humanWins = model.match.countGamesWonBy(human.getName());
int humanLosses = model.match.getGamesPlayedCount() - humanWins;
statsLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.WON) + humanWins
+ ForgeProps.getLocalized(WINLOSE_TEXT.LOST) + humanLosses);
//show "You Won" or "You Lost"
if (model.match.hasHumanWonLastGame()) {
if (model.match.hasWonLastGame(human.getName())) {
titleLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.WIN));
} else {
titleLabel.setText(ForgeProps.getLocalized(WINLOSE_TEXT.LOSE));
@@ -244,15 +244,16 @@ public class Gui_WinLose extends JFrame implements NewConstants {
StringBuilder sb = new StringBuilder("<html>");
boolean hasNeverLost = true;
Player computer = AllZone.getComputerPlayer();
for (GameSummary game : matchState.getGamesPlayed()) {
if (game.isAIWinner()) {
hasNeverLost = true;
if (game.isWinner(computer.getName())) {
hasNeverLost = false;
continue; // no rewards for losing a game
}
GamePlayerRating aiRating = game.getPlayerRating(PlayerIndex.AI);
GamePlayerRating humanRating = game.getPlayerRating(PlayerIndex.HUMAN);
GamePlayerRating aiRating = game.getPlayerRating(computer.getName());
GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName());
GameLossReason whyAiLost = aiRating.getLossReason();
int rewardAltWinCondition = q.getRewards().getCreditsRewardForAltWin(whyAiLost);
@@ -344,7 +345,7 @@ public class Gui_WinLose extends JFrame implements NewConstants {
} else { //Quest
boolean wonMatch = false;
if (model.match.isMatchWonByHuman()) {
if (model.match.isMatchWonBy(AllZone.getHumanPlayer().getName())) {
model.quest.addWin();
wonMatch = true;
} else {

View File

@@ -1,5 +1,8 @@
package forge.game;
import java.util.HashMap;
import java.util.Map;
/**
* <p>GameInfo class.</p>
@@ -8,49 +11,44 @@ package forge.game;
* @version $Id$
*/
// This should be divided into two: the very summary (immutable with only getters) and
// This class might be divided in two parts: the very summary (immutable with only getters) and
// GameObserver class - who should be notified of any considerable ingame event
public class GameSummary {
protected int playerWinner = PlayerIndex.UNDEFINED;
protected int playerGotFirstTurn = PlayerIndex.UNDEFINED;
public final class GameSummary {
protected String playerWinner = "Nobody";
protected String playerGotFirstTurn = "Nobody";
protected int lastTurnNumber = 0;
protected GameEndReason winCondition;
protected String spellEffectWin;
protected GamePlayerRating playerRating[] = new GamePlayerRating[2/*players*/];
protected final Map<String, GamePlayerRating> playerRating = new HashMap<String, GamePlayerRating>();
public GameSummary()
public GameSummary(String... names)
{
playerRating[PlayerIndex.AI] = new GamePlayerRating();
playerRating[PlayerIndex.HUMAN] = new GamePlayerRating();
for (String n : names) {
playerRating.put(n, new GamePlayerRating());
}
}
public final void end( final GameEndReason condition, int iPlayerWinner, String spellEffectWin )
public final void end( final GameEndReason condition, String winner, String spellEffect )
{
winCondition = condition;
playerWinner = iPlayerWinner;
this.spellEffectWin = spellEffectWin;
playerWinner = winner;
spellEffectWin = spellEffect;
}
public final boolean isHumanWinner() { return PlayerIndex.HUMAN == playerWinner; }
public final boolean isAIWinner() { return PlayerIndex.AI == playerWinner; }
public final boolean isDraw() { return PlayerIndex.DRAW == playerWinner; }
public final boolean isDraw() { return null == playerWinner; }
public final boolean isWinner(String name) { return name != null && name.equals(playerWinner); }
public String getWinner() { return playerWinner; }
public GameEndReason getWinCondition() { return winCondition; }
public GamePlayerRating getPlayerRating(int iPlayer) {
if (iPlayer >= 0 && iPlayer < playerRating.length) {
return playerRating[iPlayer];
}
return null;
}
public GamePlayerRating getPlayerRating(String name) { return playerRating.get(name); }
public int getTurnGameEnded() {
return lastTurnNumber;
}
public final void setPlayerWhoGotFirstTurn(int iPlayer)
public final void setPlayerWhoGotFirstTurn(String playerName)
{
playerGotFirstTurn = iPlayer;
playerGotFirstTurn = playerName;
}
public void notifyNextTurn() {

View File

@@ -7,6 +7,7 @@ public enum GameType {
Constructed(false),
Sealed(true),
Draft(true),
Commander(false),
Quest(true);
private final boolean bLimited;

View File

@@ -1,8 +0,0 @@
package forge.game;
public interface PlayerIndex {
int UNDEFINED = Integer.MIN_VALUE;
int DRAW = -1;
int HUMAN = 0;
int AI = 1;
}

View File

@@ -16,7 +16,6 @@ import forge.Player;
import forge.card.abilityFactory.AbilityFactory;
import forge.card.spellability.SpellAbility;
import forge.game.GamePlayerRating;
import forge.game.PlayerIndex;
import forge.quest.data.QuestData;
/**
@@ -68,9 +67,9 @@ public class Input_Mulligan extends Input {
/** {@inheritDoc} */
@Override
public final void selectButtonCancel() {
GamePlayerRating humanRating = AllZone.getGameInfo().getPlayerRating(PlayerIndex.HUMAN);
Player humanPlayer = AllZone.getHumanPlayer();
GamePlayerRating humanRating = AllZone.getGameInfo().getPlayerRating(humanPlayer.getName());
int newHand = doMulligan(humanPlayer, humanRating);
QuestData quest = AllZone.getQuestData();
@@ -90,7 +89,7 @@ public class Input_Mulligan extends Input {
final void end() {
//Computer mulligan
Player aiPlayer = AllZone.getComputerPlayer();
GamePlayerRating aiRating = AllZone.getGameInfo().getPlayerRating(PlayerIndex.AI);
GamePlayerRating aiRating = AllZone.getGameInfo().getPlayerRating(aiPlayer.getName());
boolean aiTakesMulligan = true;
//Computer mulligans if there are no cards with converted mana cost of 0 in its hand

View File

@@ -14,14 +14,19 @@ import forge.Player;
import forge.PlayerZone;
import forge.StaticEffects;
import forge.Upkeep;
import forge.Constant.Zone;
import forge.card.trigger.TriggerHandler;
import forge.game.GameSummary;
/**
* Represents the Forge Game State.
*/
public class FGameState {
private Player humanPlayer = new HumanPlayer("Human");
private Player computerPlayer = new AIPlayer("Computer");
public static final String HUMAN_PLAYER_NAME = "Human";
public static final String AI_PLAYER_NAME = "Computer";
private Player humanPlayer = new HumanPlayer(HUMAN_PLAYER_NAME);
private Player computerPlayer = new AIPlayer(AI_PLAYER_NAME);
private EndOfTurn endOfTurn = new EndOfTurn();
private EndOfCombat endOfCombat = new EndOfCombat();
private Upkeep upkeep = new Upkeep();
@@ -36,6 +41,7 @@ public class FGameState {
private PlayerZone stackZone = new DefaultPlayerZone(Constant.Zone.Stack, null);
private long timestamp = 0;
private GameSummary gameInfo;
/**
* Constructor.
@@ -264,4 +270,32 @@ public class FGameState {
this.timestamp = timestamp0;
}
public GameSummary getGameInfo() {
return gameInfo;
}
/**
* Call this each time you start a new game, ok?
*/
public void newGameCleanup() {
gameInfo = new GameSummary(humanPlayer.getName(), computerPlayer.getName());
getHumanPlayer().reset();
getComputerPlayer().reset();
getPhase().reset();
getStack().reset();
getCombat().reset();
for (Player p : getPlayers()) {
for(Zone z : Player.ALL_ZONES) {
p.getZone(z).reset();
}
}
getStaticEffects().reset();
}
}

View File

@@ -1,7 +1,9 @@
package forge.quest.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import forge.game.GameSummary;
@@ -33,43 +35,41 @@ public class QuestMatchState {
return gamesPlayed.size();
}
public final boolean hasHumanWonLastGame() {
public final boolean hasWonLastGame(String playerName) {
int iLastGame = gamesPlayed.size() - 1;
return iLastGame >= 0 ? gamesPlayed.get(iLastGame).isHumanWinner() : false;
return iLastGame >= 0 ? gamesPlayed.get(iLastGame).isWinner(playerName) : false;
}
public final boolean isMatchOver() {
int winsHuman = 0;
int winsAI = 0;
int totalGames = 0;
Map<String, Integer> winsCount = new HashMap<String, Integer>();
for (GameSummary game : gamesPlayed) {
if (game.isAIWinner()) { winsAI++; }
if (game.isHumanWinner()) { winsHuman++; }
String winner = game.getWinner();
Integer boxedWins = winsCount.get(winner);
int wins = boxedWins == null ? 0 : boxedWins.intValue();
winsCount.put(winner, wins + 1);
totalGames++;
}
return winsAI >= MIN_GAMES_TO_WIN_MATCH || winsHuman >= MIN_GAMES_TO_WIN_MATCH || totalGames >= GAMES_PER_MATCH;
}
public final int getGamesCountWonByHuman() {
int winsHuman = 0;
for (GameSummary game : gamesPlayed) {
if (game.isHumanWinner()) { winsHuman++; }
int maxWins = 0;
for (Integer win : winsCount.values()) {
maxWins = Math.max(maxWins, win);
}
return winsHuman;
return maxWins >= MIN_GAMES_TO_WIN_MATCH || totalGames >= GAMES_PER_MATCH;
}
public final int getGamesCountLostByHuman() {
int lossHuman = 0;
public final int countGamesWonBy(String name) {
int wins = 0;
for (GameSummary game : gamesPlayed) {
if (!game.isHumanWinner()) { lossHuman++; }
if (game.isWinner(name)) { wins++; }
}
return lossHuman;
return wins;
}
public final boolean isMatchWonByHuman() {
return getGamesCountWonByHuman() >= MIN_GAMES_TO_WIN_MATCH;
public final boolean isMatchWonBy(String name) {
return countGamesWonBy(name) >= MIN_GAMES_TO_WIN_MATCH;
}
public final void reset() {

View File

@@ -1,10 +1,11 @@
package forge.quest.data;
import forge.AllZone;
import forge.MyRandom;
import forge.Player;
import forge.game.GameLossReason;
import forge.game.GamePlayerRating;
import forge.game.GameSummary;
import forge.game.PlayerIndex;
/**
* Helper class to deal with rewards given in quest.
@@ -47,14 +48,16 @@ public class QuestUtilRewards {
+ (QuestPreferences.getMatchRewardTotalWins() * q.getWin()));
boolean hasNeverLost = true;
Player computer = AllZone.getComputerPlayer();
for (GameSummary game : matchState.getGamesPlayed()) {
if (game.isAIWinner()) {
hasNeverLost = true;
if (game.isWinner(computer.getName())) {
hasNeverLost = false;
continue; // no rewards for losing a game
}
GamePlayerRating aiRating = game.getPlayerRating(PlayerIndex.AI);
GamePlayerRating humanRating = game.getPlayerRating(PlayerIndex.HUMAN);
GamePlayerRating aiRating = game.getPlayerRating(computer.getName());
GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName());
GameLossReason whyAiLost = aiRating.getLossReason();
creds += getCreditsRewardForAltWin(whyAiLost);