diff options
Diffstat (limited to 'src/jrummikub/control/RoundControl.java')
-rw-r--r-- | src/jrummikub/control/RoundControl.java | 166 |
1 files changed, 143 insertions, 23 deletions
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<StoneSet> 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<StoneSet> invalidSets) { this.table = (ITable) table.clone(); @@ -55,14 +84,29 @@ public class RoundControl { this.invalidSets = new ArrayList<StoneSet>(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<StoneSet> 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.<Stone> emptyList()); view.setInvalidStoneSets(Collections.<StoneSet> 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<Boolean> winners = new ArrayList<Boolean>(); List<Integer> points = new ArrayList<Integer>(); @@ -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<Integer, Integer> updateBestScore( Pair<Integer, Integer> 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<Connection>(connections)) { |