mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
removed PlayerIndex, players' stats are keyed by name, allowing multiple uniquely-named players
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -9761,7 +9761,6 @@ src/main/java/forge/game/GameLossReason.java -text
|
||||
src/main/java/forge/game/GamePlayerRating.java -text
|
||||
src/main/java/forge/game/GameSummary.java svneol=native#text/plain
|
||||
src/main/java/forge/game/GameType.java -text
|
||||
src/main/java/forge/game/PlayerIndex.java -text
|
||||
src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain
|
||||
src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain
|
||||
src/main/java/forge/game/limited/BoosterDraft_1.java svneol=native#text/plain
|
||||
|
||||
@@ -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();
|
||||
Singletons.getModel().getGameState().newGameCleanup();
|
||||
|
||||
getHumanPlayer().reset();
|
||||
getComputerPlayer().reset();
|
||||
|
||||
getPhase().reset();
|
||||
getStack().reset();
|
||||
getCombat().reset();
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -7,6 +7,7 @@ public enum GameType {
|
||||
Constructed(false),
|
||||
Sealed(true),
|
||||
Draft(true),
|
||||
Commander(false),
|
||||
Quest(true);
|
||||
|
||||
private final boolean bLimited;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package forge.game;
|
||||
|
||||
public interface PlayerIndex {
|
||||
int UNDEFINED = Integer.MIN_VALUE;
|
||||
int DRAW = -1;
|
||||
int HUMAN = 0;
|
||||
int AI = 1;
|
||||
}
|
||||
@@ -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,8 +67,8 @@ 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
int maxWins = 0;
|
||||
for (Integer win : winsCount.values()) {
|
||||
maxWins = Math.max(maxWins, win);
|
||||
}
|
||||
|
||||
public final int getGamesCountWonByHuman() {
|
||||
int winsHuman = 0;
|
||||
return maxWins >= MIN_GAMES_TO_WIN_MATCH || totalGames >= GAMES_PER_MATCH;
|
||||
}
|
||||
|
||||
public final int countGamesWonBy(String name) {
|
||||
int wins = 0;
|
||||
for (GameSummary game : gamesPlayed) {
|
||||
if (game.isHumanWinner()) { winsHuman++; }
|
||||
if (game.isWinner(name)) { wins++; }
|
||||
}
|
||||
return winsHuman;
|
||||
return wins;
|
||||
}
|
||||
|
||||
public final int getGamesCountLostByHuman() {
|
||||
int lossHuman = 0;
|
||||
for (GameSummary game : gamesPlayed) {
|
||||
if (!game.isHumanWinner()) { lossHuman++; }
|
||||
}
|
||||
return lossHuman;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user