package magic.ui.duel.viewerinfo; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import magic.model.MagicCard; import magic.model.MagicCardList; import magic.model.MagicGame; import magic.model.MagicMessage; import magic.model.MagicPermanent; import magic.model.MagicPlayer; import magic.model.MagicPlayerZone; import magic.model.phase.MagicPhaseType; import magic.model.stack.MagicCardOnStack; import magic.model.stack.MagicItemOnStack; public class GameViewerInfo { private static final int MAX_LOG = 50; private final PlayerViewerInfo playerInfo; private final PlayerViewerInfo opponentInfo; private final PlayerViewerInfo priorityPlayer; private final List<StackViewerInfo> stack = new ArrayList<>(); private final List<MagicMessage> log = new ArrayList<>(MAX_LOG); private final int turn; private final int gamesRequiredToWin; private final int gameNumber; private final int maxGames; private final MagicPhaseType phaseType; private final int undoPoints; public GameViewerInfo(final MagicGame game) { final MagicPlayer player = game.getVisiblePlayer(); playerInfo = new PlayerViewerInfo(game, player); opponentInfo = new PlayerViewerInfo(game, player.getOpponent()); priorityPlayer = game.getPriorityPlayer() == player ? playerInfo : opponentInfo; // TODO: MagicPlayer should be responsible for keeping track of games won. playerInfo.setGamesWon(game.getDuel().getGamesWon()); opponentInfo.setGamesWon(game.getDuel().getGamesPlayed() - game.getDuel().getGamesWon()); turn = game.getTurn(); gamesRequiredToWin = game.getDuel().getConfiguration().getGamesRequiredToWinDuel(); gameNumber = game.getDuel().getGameNr(); maxGames = game.getDuel().getGamesTotal(); phaseType = game.getPhase().getType(); undoPoints = game.getNrOfUndoPoints(); setStackViewerInfo(game); setLogBookViewerInfo(game); } public List<PlayerViewerInfo> getPlayers() { return Arrays.asList(playerInfo, opponentInfo); } private void setStackViewerInfo(final MagicGame game) { for (final MagicItemOnStack itemOnStack : game.getStack()) { stack.add(new StackViewerInfo(game,itemOnStack)); } } /** * make a copy of the last MAX_LOG messages. */ private void setLogBookViewerInfo(final MagicGame game) { int n = game.getLogBook().size(); final Iterator<MagicMessage> iter = game.getLogBook().listIterator(Math.max(0, n - MAX_LOG)); while (iter.hasNext()) { log.add(iter.next()); } } public PlayerViewerInfo getPlayerInfo(final boolean opponent) { return opponent ? opponentInfo : playerInfo; } public PlayerViewerInfo getAttackingPlayerInfo() { return playerInfo.isPlayerTurn() ? playerInfo : opponentInfo; } public PlayerViewerInfo getDefendingPlayerInfo() { return playerInfo.isPlayerTurn() ? opponentInfo : playerInfo; } public PlayerViewerInfo getTurnPlayer() { return playerInfo.isPlayerTurn() ? playerInfo : opponentInfo; } public PlayerViewerInfo getPriorityPlayer() { return priorityPlayer; } public boolean isVisiblePlayer(final MagicPlayer player) { return playerInfo.player==player; } public List<StackViewerInfo> getStack() { return stack; } public List<MagicMessage> getLog() { return log; } public CardViewerInfo getCardViewerInfo(long magicCardId) { final PlayerViewerInfo[] players = new PlayerViewerInfo[] {playerInfo, opponentInfo}; // first check permanents... final MagicPermanent perm = searchForCardInPermanents(magicCardId, players); if (perm != null) { return new CardViewerInfo(perm); } // ... then check stack... final MagicCardOnStack item = searchForCardOnStack(magicCardId); if (item != null) { return new CardViewerInfo(item); } // ... otherwise search through player zones in following order final MagicPlayerZone[] zones = new MagicPlayerZone[]{ MagicPlayerZone.GRAVEYARD, MagicPlayerZone.EXILE, MagicPlayerZone.HAND, MagicPlayerZone.LIBRARY }; MagicCard card = MagicCard.NONE; for (MagicPlayerZone aZone : zones) { if (card == MagicCard.NONE) { card = searchForCardInZone(magicCardId, aZone, players); } else { break; } } return new CardViewerInfo(card); } public CardViewerInfo getCardViewerInfo(MagicCard aCard) { CardViewerInfo info = getCardViewerInfo(aCard.getId()); if (info.isEmpty()) { // A land card that has been played but not yet placed cannot be found // by its Id so so need to set specifically. info = new CardViewerInfo(aCard); } return info; } private MagicCardOnStack searchForCardOnStack(long magicCardId) { for (StackViewerInfo item : stack) { if (item.isMagicCard(magicCardId)) { return (MagicCardOnStack) item.itemOnStack; } } return null; } private MagicCardList getMagicCardList(MagicPlayerZone aZone, PlayerViewerInfo aPlayer) { switch (aZone) { case GRAVEYARD: return aPlayer.graveyard; case EXILE: return aPlayer.exile; case HAND: return aPlayer.hand; case LIBRARY: return aPlayer.library; } throw new RuntimeException("Invalid MagicPlayerZone : " + aZone); } private MagicCard searchForCardInZone(long magicCardId, MagicPlayerZone zone, PlayerViewerInfo[] players) { for (final PlayerViewerInfo player : players) { final MagicCardList cards = getMagicCardList(zone, player); for (final MagicCard card : cards) { if (card.getId() == magicCardId) { return card; } } } return MagicCard.NONE; } private MagicPermanent searchForCardInPermanents(long magicCardId, PlayerViewerInfo[] players) { for (final PlayerViewerInfo player : players) { for (final PermanentViewerInfo info : player.permanents) { if (info.magicCardId == magicCardId) { return info.permanent; } } } return null; } public int getTurn() { return turn; } public int getGamesRequiredToWinDuel() { return this.gamesRequiredToWin; } public int getGameNumber() { return this.gameNumber; } public int getMaxGames() { return this.maxGames; } public MagicPhaseType getPhaseType() { return this.phaseType; } public int getUndoPoints() { return this.undoPoints; } }