From 5e3ce21569f5adc92c969735c88af488cf581916 Mon Sep 17 00:00:00 2001 From: Ida Massow Date: Tue, 21 Jun 2011 13:47:15 +0200 Subject: =?UTF-8?q?Das=20reine=20control-package=20ist=20vollst=C3=A4ndig?= =?UTF-8?q?=20kommentiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@545 72836036-5685-4462-b002-a69064685172 --- src/jrummikub/control/AbstractSettingsControl.java | 74 ++++++++- src/jrummikub/control/ApplicationControl.java | 18 +++ src/jrummikub/control/GameControl.java | 79 +++++++--- src/jrummikub/control/LoginControl.java | 1 - src/jrummikub/control/RoundControl.java | 166 ++++++++++++++++++--- src/jrummikub/control/SaveControl.java | 14 ++ src/jrummikub/control/SettingsControl.java | 17 ++- 7 files changed, 321 insertions(+), 48 deletions(-) diff --git a/src/jrummikub/control/AbstractSettingsControl.java b/src/jrummikub/control/AbstractSettingsControl.java index ee0c96c..2904df4 100644 --- a/src/jrummikub/control/AbstractSettingsControl.java +++ b/src/jrummikub/control/AbstractSettingsControl.java @@ -49,6 +49,9 @@ public abstract class AbstractSettingsControl { .asList(ISettingsPanel.PLAYER_COLORS))); } + /** + * Add event listeners to abstract settings control + */ protected void addListeners() { addPlayerSettingsListeners(); @@ -57,6 +60,9 @@ public abstract class AbstractSettingsControl { addVariantListeners(); } + /** + * Add event listeners to the player settings panel + */ private void addPlayerSettingsListeners() { connections.add(view.getSettingsPanel().getAddPlayerEvent() .add(new IListener() { @@ -95,6 +101,9 @@ public abstract class AbstractSettingsControl { })); } + /** + * Add the first half of event listeners to option panel + */ private void addOptionListeners1() { connections.add(view.getSettingsPanel() .getChangeInitialMeldThresholdEvent() @@ -134,6 +143,9 @@ public abstract class AbstractSettingsControl { })); } + /** + * Add the second half of event listeners to option panel + */ private void addOptionListeners2() { connections.add(view.getSettingsPanel().getChangeHighestValueEvent() .add(new IListener1() { @@ -168,7 +180,7 @@ public abstract class AbstractSettingsControl { update(); } })); - + connections.add(view.getSettingsPanel().getChangeSeeHandSizeEvent() .add(new IListener1() { @Override @@ -212,6 +224,11 @@ public abstract class AbstractSettingsControl { view.showSettingsPanel(true); } + /** + * Finds the next unused player color + * + * @return an unused color + */ protected Color findUnusedColor() { Color color = null; colorLoop: for (Color c : ISettingsPanel.PLAYER_COLORS) { @@ -226,6 +243,14 @@ public abstract class AbstractSettingsControl { return color; } + /** + * Sets a player's color + * + * @param i + * index of player + * @param color + * color to be set + */ private void setPlayerColor(int i, Color color) { PlayerSettings player = settings.getPlayerList().get(i); @@ -244,16 +269,36 @@ public abstract class AbstractSettingsControl { update(); } + /** + * Sets a player's name + * + * @param i + * index of player + * @param name + * name to be set + */ private void setPlayerName(int i, String name) { settings.getPlayerList().get(i).setName(name); update(); } + /** + * Removes a player from the planned game + * + * @param i + * index of player + */ private void removePlayer(int i) { settings.getPlayerList().remove(i); update(); } + /** + * Checks the settings for ambiguous or missing data and sets error/warning + * if necessary + * + * @return boolean check correct + */ protected boolean checkSettings() { if (!checkName()) { return false; @@ -270,6 +315,11 @@ public abstract class AbstractSettingsControl { return true; } + /** + * Checks if unique player name is present for each player + * + * @return is player name ok + */ private boolean checkName() { for (PlayerSettings player : settings.getPlayerList()) { if (player.getName().isEmpty()) { @@ -302,6 +352,11 @@ public abstract class AbstractSettingsControl { return true; } + /** + * Check options leading to errors + * + * @return options ok + */ private boolean checkErrors() { int totalStonesDealt = settings.getNumberOfStonesDealt() * settings.getPlayerList().size(); @@ -324,6 +379,9 @@ public abstract class AbstractSettingsControl { return true; } + /** + * Check all options and player settings for entries causing warnings + */ private void checkWarnings() { if (settings.getInitialMeldThreshold() >= 100) { view.getSettingsPanel().setError( @@ -356,10 +414,24 @@ public abstract class AbstractSettingsControl { } } + /** + * Add new player to the planned game + */ abstract protected void addPlayer(); + /** + * Set the type of a player + * + * @param i + * index of player + * @param type + * type to be set + */ abstract protected void setPlayerType(int i, Type type); + /** + * Show newly chosen options in view + */ abstract protected void update(); } diff --git a/src/jrummikub/control/ApplicationControl.java b/src/jrummikub/control/ApplicationControl.java index 752cb3c..71de63e 100644 --- a/src/jrummikub/control/ApplicationControl.java +++ b/src/jrummikub/control/ApplicationControl.java @@ -118,6 +118,9 @@ public class ApplicationControl { }); } + /** + * Create a new network login control + */ private void createLoginControl() { loginControl = new LoginControl(view); loginControl.getLoginEvent().add(new IListener1() { @@ -135,6 +138,9 @@ public class ApplicationControl { loginControl.startLogin(); } + /** + * End all controls in case of e.g. quit event + */ private void abortControls() { if (settingsControl != null) { settingsControl.abort(); @@ -191,6 +197,12 @@ public class ApplicationControl { settingsControl.startSettings(); } + /** + * Adds events listeners to game control events + * + * @param gameControl + * of current game + */ private void addGameControlListeners(GameControl gameControl) { gameControl.getEndOfGameEvent().add(new IListener() { @Override @@ -200,6 +212,12 @@ public class ApplicationControl { }); } + /** + * Create a new network game control + * + * @param loginData + * users login data for channel + */ private void createNetworkControl(LoginData loginData) { ConnectionControl connectionControl = new ConnectionControl(loginData); networkControl = new NetworkControl(loginData, connectionControl, diff --git a/src/jrummikub/control/GameControl.java b/src/jrummikub/control/GameControl.java index c038f9a..736e440 100644 --- a/src/jrummikub/control/GameControl.java +++ b/src/jrummikub/control/GameControl.java @@ -33,11 +33,11 @@ public class GameControl { * Constructor * * @param gameSettings - * the game settings + * the game settings * @param saveControl - * the save control + * the save control * @param view - * the view + * the view */ public GameControl(GameSettings gameSettings, SaveControl saveControl, IView view) { @@ -49,8 +49,9 @@ public class GameControl { gameState = new GameState(); saveControl.setGameState(gameState); - gameState.setFirstRoundFirstPlayer((int) (Math.random() * gameSettings - .getPlayerList().size())); + gameState + .setFirstRoundFirstPlayer((int) (Math.random() * gameSettings + .getPlayerList().size())); } connections.add(view.getNewRoundEvent().add(new IListener() { @@ -84,11 +85,17 @@ public class GameControl { return endOfGameEvent; } + /** + * Ends the running game + */ private void endGame() { removeListeners(); endOfGameEvent.emit(); } + /** + * Removes all listeners from the connection + */ private void removeListeners() { for (Connection c : connections) { c.remove(); @@ -106,9 +113,9 @@ public class GameControl { * Continues game after loading * * @param gameState - * the saved GameState (Players, startplayer, points) + * the saved GameState (Players, startplayer, points) * @param roundState - * the saved RoundState (activePlayer, Table, heap etc) + * the saved RoundState (activePlayer, Table, heap etc) */ public void continueGame(GameState gameState, IRoundState roundState) { this.gameState = gameState; @@ -135,6 +142,9 @@ public class GameControl { view.clearView(); } + /** + * Start a new round within the existing game + */ protected void startRound() { if (roundControl != null) { return; @@ -147,22 +157,29 @@ public class GameControl { roundControl.startRound(); } + /** + * Prepare a new round by setting start player, adding listeners + * + * @param roundState + * of current round + */ private void prepareRound(IRoundState roundState) { saveControl.setRoundState(roundState); if (roundState != null) { - roundState.setActivePlayerNumber(gameState.getFirstRoundFirstPlayer() - + gameState.getScores().size()); + roundState.setActivePlayerNumber(gameState + .getFirstRoundFirstPlayer() + gameState.getScores().size()); } roundControl = createRoundControl(roundState); - roundControl.getRoundStateUpdateEvent().add(new IListener1() { - @Override - public void handle(IRoundState newState) { - gameState = newState.getGameState(); - gameSettings = newState.getGameSettings(); - } - }); + roundControl.getRoundStateUpdateEvent().add( + new IListener1() { + @Override + public void handle(IRoundState newState) { + gameState = newState.getGameState(); + gameSettings = newState.getGameSettings(); + } + }); roundControl.getEndOfRoundEvent().add(new IListener1() { @Override public void handle(Score roundScore) { @@ -179,19 +196,40 @@ public class GameControl { }); } + /** + * Creates a new round State + * + * @return the round state + */ protected IRoundState createRoundState() { return new RoundState(gameSettings, gameState); } + /** + * Creates a new round control with the specified round state + * + * @param roundState + * for new round control + * @return the round control + */ protected RoundControl createRoundControl(IRoundState roundState) { return new RoundControl(roundState, view); } + /** + * Restarts round after loading + */ private void restartRound() { roundControl = null; startRound(); } + /** + * Sets the score and default values for saving when round ends + * + * @param roundScore + * score for ended round + */ private void endOfRound(Score roundScore) { gameState.getScores().add(roundScore); saveControl.setRoundState(null); @@ -200,17 +238,24 @@ public class GameControl { showScorePanel(); } + /** + * Sets score panel visible + */ private void showScorePanel() { view.showSidePanel(false); view.setBottomPanel(BottomPanelType.WIN_PANEL); view.getScorePanel().setPlayers(gameSettings.getPlayerList()); view.getScorePanel().setScores(gameState.getScores()); - view.getScorePanel().setAccumulatedScore(gameState.getAccumulatedScore()); + view.getScorePanel().setAccumulatedScore( + gameState.getAccumulatedScore()); view.getScorePanel().update(); view.showScorePanel(true); } + /** + * Exits System without warnings if no game control is active + */ private void endProgram() { System.exit(0); } diff --git a/src/jrummikub/control/LoginControl.java b/src/jrummikub/control/LoginControl.java index ccf6e2e..f26b0d6 100644 --- a/src/jrummikub/control/LoginControl.java +++ b/src/jrummikub/control/LoginControl.java @@ -36,7 +36,6 @@ public class LoginControl { @Override public void handle(LoginData loginData) { abort(); - // TODO connectPanel anzeigen loginEvent.emit(loginData); } })); diff --git a/src/jrummikub/control/RoundControl.java b/src/jrummikub/control/RoundControl.java index c24a7f5..b378430 100644 --- a/src/jrummikub/control/RoundControl.java +++ b/src/jrummikub/control/RoundControl.java @@ -37,10 +37,29 @@ import jrummikub.view.IView.BottomPanelType; * Controller that manages a single round of rummikub */ public class RoundControl { + /** + * Enum summarizing the different types of invalid turns to set the correct + * panel message + */ public enum InvalidTurnType { - INVALID_SETS, INITIAL_MELD_ERROR, NOT_ENOUGH_POINTS + /** There are invalid set(s) on the table */ + INVALID_SETS, + /** + * The player tried to modify the table without providing the initial + * meld threshold first + */ + INITIAL_MELD_ERROR, + /** + * The player didn't provide enough points for the initial meld + * threshold + */ + NOT_ENOUGH_POINTS } + /** + * Table, stone sets and type of an invalid turn to allow a user to track + * his own errors + */ public static class InvalidTurnInfo implements Serializable { private static final long serialVersionUID = -3591000741414366776L; @@ -48,6 +67,16 @@ public class RoundControl { private InvalidTurnType type; private ArrayList invalidSets; + /** + * Creates new InvalidTurnInfo + * + * @param table + * the table after the turn + * @param type + * the type of the invalid turn + * @param invalidSets + * the sets causing the turn to be invalid + */ public InvalidTurnInfo(ITable table, InvalidTurnType type, Collection invalidSets) { this.table = (ITable) table.clone(); @@ -55,14 +84,29 @@ public class RoundControl { this.invalidSets = new ArrayList(invalidSets); } + /** + * Getter for table + * + * @return the table + */ public ITable getTable() { return table; } + /** + * Getter for invalid turn type + * + * @return the type + */ public InvalidTurnType getType() { return type; } + /** + * Getter for the invalid sets + * + * @return invalid sets + */ public List getInvalidSets() { return invalidSets; } @@ -86,9 +130,9 @@ public class RoundControl { * Create a new RoundControl using the given gameState and view * * @param roundState - * initial round state + * initial round state * @param view - * view used for user interaction + * view used for user interaction */ protected RoundControl(IRoundState roundState, IView view, boolean mayPause) { this.roundState = roundState; @@ -160,11 +204,21 @@ public class RoundControl { } } + /** + * Sets the current round state + * + * @param state + * to be set + */ protected void setRoundState(IRoundState state) { roundState = state; roundStateUpdateEvent.emit(state); } + /** + * Prepare a player's turn by checking the player types and setting the + * correct turn control + */ protected void prepareTurn() { doPrepareTurn(); @@ -178,6 +232,9 @@ public class RoundControl { } } + /** + * Prepare turn by setting the view components + */ protected void doPrepareTurn() { updateSidePanel(); @@ -190,16 +247,20 @@ public class RoundControl { } view.getTablePanel().setStoneSets(roundState.getTable().clone()); - view.setCurrentPlayerName(roundState.getActivePlayer().getPlayerSettings() - .getName()); - view.setCurrentPlayerColor(roundState.getActivePlayer().getPlayerSettings() - .getColor()); - view.setCurrentPlayerHasLaidOut(roundState.getActivePlayer().getLaidOut()); + view.setCurrentPlayerName(roundState.getActivePlayer() + .getPlayerSettings().getName()); + view.setCurrentPlayerColor(roundState.getActivePlayer() + .getPlayerSettings().getColor()); + view.setCurrentPlayerHasLaidOut(roundState.getActivePlayer() + .getLaidOut()); turnControl = createTurnControl(roundState.getActivePlayer() .getPlayerSettings().getType()); } + /** + * Start a players turn with the correct turn control + */ protected void startTurn() { if (turnControl == null) { doPrepareTurn(); @@ -250,6 +311,9 @@ public class RoundControl { turnControl.startTurn(); } + /** + * Update the side panel to show correct player order and heap size + */ private void updateSidePanel() { view.showSidePanel(true); view.getSidePanel().setGameSettings(roundState.getGameSettings()); @@ -263,25 +327,49 @@ public class RoundControl { view.getSidePanel().setHeapSize(roundState.getGameHeap().getSize()); } - /** Override this */ + /** + * Override this + * + * @param turnControl + * current turn control + */ protected void addTurnControlListeners(ITurnControl turnControl) { } + /** + * Creates new turn control of the specified type + * + * @param type + * of the new turn control + * @return the new turn control + */ protected ITurnControl createTurnControl(Type type) { return TurnControlFactory.getFactory(type).create(); } + /** + * Deal each player the number of stones specified in the game settings + * (numberOfStonesDealt) + */ protected void deal() { for (int i = 0; i < roundState.getPlayerCount(); i++) { IHand hand = roundState.getNthNextPlayer(i).getHand(); - for (int j = 0; j < roundState.getGameSettings().getNumberOfStonesDealt(); j++) { - hand.drop(roundState.getGameHeap().drawStone(), new Position(0, 0)); + for (int j = 0; j < roundState.getGameSettings() + .getNumberOfStonesDealt(); j++) { + hand.drop(roundState.getGameHeap().drawStone(), new Position(0, + 0)); } } view.getSidePanel().setHeapSize(roundState.getGameHeap().getSize()); } + /** + * End the players turn + * + * @param invalidTurnInfo + * info about the player's last turn + */ protected void endOfTurn(InvalidTurnInfo invalidTurnInfo) { boolean wasAI = turnControl instanceof AIControl; boolean wasHuman = turnControl instanceof HumanTurnControl; @@ -298,16 +386,16 @@ public class RoundControl { view.setInvalidStoneSets(invalidTurnInfo.getInvalidSets()); switch (invalidTurnInfo.getType()) { - case INITIAL_MELD_ERROR: - view.setInitialMeldFirstError(); - break; - case INVALID_SETS: - view.setStoneCollectionHidden(true); - break; - case NOT_ENOUGH_POINTS: - view.setInitialMeldError(roundState.getGameSettings() - .getInitialMeldThreshold()); - break; + case INITIAL_MELD_ERROR: + view.setInitialMeldFirstError(); + break; + case INVALID_SETS: + view.setStoneCollectionHidden(true); + break; + case NOT_ENOUGH_POINTS: + view.setInitialMeldError(roundState.getGameSettings() + .getInitialMeldThreshold()); + break; } if (wasAI) { @@ -330,6 +418,9 @@ public class RoundControl { } } + /** + * Set the next player as active player if the round is not finished + */ protected void nextPlayer() { view.setSelectedStones(Collections. emptyList()); view.setInvalidStoneSets(Collections. emptyList()); @@ -356,6 +447,9 @@ public class RoundControl { } } + /** + * Ends the current round and emits an event setting the score + */ void endOfRound() { removeListeners(); Score roundScore = score(); @@ -363,12 +457,20 @@ public class RoundControl { roundFinished = true; } + /** + * Removes all listeners form the connections + */ private void removeListeners() { for (Connection c : connections) { c.remove(); } } + /** + * Calculate the score for the current round and the total game score + * + * @return the new score + */ private Score score() { List winners = new ArrayList(); List points = new ArrayList(); @@ -393,10 +495,12 @@ public class RoundControl { stonePoints = playerHand.isInitialMeldPossible(roundState .getGameSettings()) ? 200 : 100; } else { - stonePoints = playerHand.getStonePoints(roundState.getGameSettings()); + stonePoints = playerHand.getStonePoints(roundState + .getGameSettings()); } - bestScore = updateBestScore(bestScore, -stonePoints, playerHand.getSize()); + bestScore = updateBestScore(bestScore, -stonePoints, + playerHand.getSize()); points.add(-stonePoints); pointSum += stonePoints; @@ -415,6 +519,18 @@ public class RoundControl { return new Score(winners, points); } + /** + * Update the best score to find the winner in case of special game end + * (everybody still has stones on hand) + * + * @param bestScore + * of previous rounds + * @param stonePoints + * sum of points still left on hands + * @param size + * number of players in game (= size of score list in columns) + * @return Pair of maximum points and hand size + */ private static Pair updateBestScore( Pair bestScore, int stonePoints, int size) { if (bestScore.getFirst() == stonePoints) { @@ -435,6 +551,10 @@ public class RoundControl { return restartRoundEvent; } + /** + * Redeal stones and restart round if a player was allowed to redeal and + * chose to do so + */ private void redeal() { turnControl = null; for (Connection c : new ArrayList(connections)) { diff --git a/src/jrummikub/control/SaveControl.java b/src/jrummikub/control/SaveControl.java index 4134aec..1b88d1c 100644 --- a/src/jrummikub/control/SaveControl.java +++ b/src/jrummikub/control/SaveControl.java @@ -107,6 +107,13 @@ public class SaveControl { this.roundState = roundState; } + /** + * Loads the specified file and sets game state and round state. If the file + * selected cannot be handled, an error will occur and show + * + * @param file + * to be loaded + */ private void load(File file) { try { ObjectInputStream stream = new ObjectInputStream( @@ -140,6 +147,13 @@ public class SaveControl { return loadErrorEvent; } + /** + * Saves the current game state and round state to a file with the specified + * file name + * + * @param file + * file to save game in + */ private void save(File file) { if (gameState == null || gameSettings == null) { return; diff --git a/src/jrummikub/control/SettingsControl.java b/src/jrummikub/control/SettingsControl.java index 6576101..4675bc7 100644 --- a/src/jrummikub/control/SettingsControl.java +++ b/src/jrummikub/control/SettingsControl.java @@ -25,9 +25,9 @@ public class SettingsControl extends AbstractSettingsControl { * Create a new settings control * * @param view - * the view to use + * the view to use * @param settings - * initial game settings + * initial game settings */ public SettingsControl(IView view, GameSettings settings) { super(view, settings); @@ -48,8 +48,8 @@ public class SettingsControl extends AbstractSettingsControl { } /** - * the start game event is emitted when the user wants to start a game and the - * settings made are valid + * the start game event is emitted when the user wants to start a game and + * the settings made are valid * * @return the event */ @@ -96,8 +96,9 @@ public class SettingsControl extends AbstractSettingsControl { view.getSettingsPanel().enableRemovePlayerButtons( Collections.nCopies(settings.getPlayerList().size(), enableRemoveButtons)); - view.getSettingsPanel().enableAddPlayerButton( - settings.getPlayerList().size() < ISettingsPanel.PLAYER_COLORS.length); + view.getSettingsPanel() + .enableAddPlayerButton( + settings.getPlayerList().size() < ISettingsPanel.PLAYER_COLORS.length); checkSettings(); @@ -109,6 +110,10 @@ public class SettingsControl extends AbstractSettingsControl { view.getSettingsPanel().setGameSettings(settings); } + /** + * Aborts the settings control and emits a start game event if settings have + * been approved + */ private void startGame() { if (!checkSettings()) { return; -- cgit v1.2.3