diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jrummikub/control/ApplicationControl.java | 46 | ||||
-rw-r--r-- | src/jrummikub/control/GameControl.java | 31 | ||||
-rw-r--r-- | src/jrummikub/control/RoundControl.java | 53 | ||||
-rw-r--r-- | src/jrummikub/control/SaveControl.java | 57 | ||||
-rw-r--r-- | src/jrummikub/control/SettingsControl.java | 8 | ||||
-rw-r--r-- | src/jrummikub/model/StoneSet.java | 9 | ||||
-rw-r--r-- | src/jrummikub/model/StoneTray.java | 3 | ||||
-rw-r--r-- | src/jrummikub/util/Event3.java | 46 | ||||
-rw-r--r-- | src/jrummikub/util/IEvent3.java | 28 | ||||
-rw-r--r-- | src/jrummikub/util/IListener3.java | 22 |
10 files changed, 257 insertions, 46 deletions
diff --git a/src/jrummikub/control/ApplicationControl.java b/src/jrummikub/control/ApplicationControl.java index a0bdf35..068b898 100644 --- a/src/jrummikub/control/ApplicationControl.java +++ b/src/jrummikub/control/ApplicationControl.java @@ -1,8 +1,11 @@ package jrummikub.control; import jrummikub.model.GameSettings; +import jrummikub.model.GameState; +import jrummikub.model.IRoundState; import jrummikub.util.IListener; import jrummikub.util.IListener1; +import jrummikub.util.IListener3; import jrummikub.view.IView; import jrummikub.view.IView.BottomPanelType; @@ -18,7 +21,7 @@ public class ApplicationControl { * Creates a new application control * * @param view - * the view to use + * the view to use */ public ApplicationControl(IView view) { this.view = view; @@ -38,25 +41,48 @@ public class ApplicationControl { public void startApplication() { view.showScorePanel(false); view.setBottomPanel(BottomPanelType.START_GAME_PANEL); - SettingsControl settingsControl = new SettingsControl(view, + saveControl.setGameSettings(null); + saveControl.setGameState(null); + final SettingsControl settingsControl = new SettingsControl(view, new GameSettings()); + saveControl.getLoadEvent().add( + new IListener3<GameSettings, GameState, IRoundState>() { + + @Override + public void handle(GameSettings settings, + GameState gameState, IRoundState roundState) { + settingsControl.abort(); + // TODO alles ordentlich beenden (controls) + GameControl gameControl = new GameControl(settings, + saveControl, view); + addGameControlListeners(gameControl); + gameControl.continueGame(gameState, roundState); + + } + }); + settingsControl.getStartGameEvent().add(new IListener1<GameSettings>() { @Override public void handle(GameSettings settings) { saveControl.setGameSettings(settings); - GameControl gameControl = new GameControl(settings, saveControl, view); - gameControl.getEndOfGameEvent().add(new IListener() { - @Override - public void handle() { - startApplication(); - } - }); - gameControl.startGame(); + GameControl gameControl = new GameControl(settings, + saveControl, view); + addGameControlListeners(gameControl); + gameControl.startGame(); } }); settingsControl.startSettings(); } + + private void addGameControlListeners(GameControl gameControl) { + gameControl.getEndOfGameEvent().add(new IListener() { + @Override + public void handle() { + startApplication(); + } + }); + } } diff --git a/src/jrummikub/control/GameControl.java b/src/jrummikub/control/GameControl.java index fb3fcf8..985781a 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) { @@ -96,6 +96,16 @@ public class GameControl { startRound(); } + public void continueGame(GameState gameState, IRoundState roundState) { + this.gameState = gameState; + if (roundState == null) { + showScorePanel(); + } else { + prepareRound(roundState); + roundControl.continueRound(); + } + } + private void startRound() { if (roundControl != null) { return; @@ -104,6 +114,11 @@ public class GameControl { view.showScorePanel(false); IRoundState roundState = new RoundState(gameSettings); + prepareRound(roundState); + roundControl.startRound(); + } + + private void prepareRound(IRoundState roundState) { saveControl.setRoundState(roundState); roundState.setActivePlayerNumber(gameState.getFirstRoundFirstPlayer() @@ -125,8 +140,6 @@ public class GameControl { restartRound(); } }); - - roundControl.startRound(); } private void restartRound() { @@ -136,13 +149,19 @@ public class GameControl { private void endOfRound(Score roundScore) { gameState.getScores().add(roundScore); + saveControl.setRoundState(null); roundControl = null; + showScorePanel(); + } + + private void showScorePanel() { 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); } diff --git a/src/jrummikub/control/RoundControl.java b/src/jrummikub/control/RoundControl.java index 5e85167..4fadc15 100644 --- a/src/jrummikub/control/RoundControl.java +++ b/src/jrummikub/control/RoundControl.java @@ -47,9 +47,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 */ public RoundControl(IRoundState roundState, IView view) { this.roundState = roundState; @@ -70,7 +70,10 @@ public class RoundControl { */ public void startRound() { deal(); + continueRound(); + } + public void continueRound() { connections.add(view.getStartTurnEvent().add(new IListener() { @Override public void handle() { @@ -91,11 +94,12 @@ public class RoundControl { : BottomPanelType.COMPUTER_HAND_PANEL); view.getTablePanel().setStoneSets(clonedTable.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()); if (!isHuman) startTurn(); @@ -120,11 +124,11 @@ public class RoundControl { view.getPlayerPanel().setEndTurnMode(turnMode); } turnControl = TurnControlFactory.getFactory( - roundState.getActivePlayer().getPlayerSettings().getTurnControlType()) - .create(); + roundState.getActivePlayer().getPlayerSettings() + .getTurnControlType()).create(); turnControl.setup(new ITurnControl.TurnInfo(clonedTable, clonedHand, - roundState.getActivePlayer().getLaidOut(), turnMode), roundState - .getGameSettings(), view); + roundState.getActivePlayer().getLaidOut(), turnMode), + roundState.getGameSettings(), view); turnControl.getEndOfTurnEvent().add(new IListener() { @Override public void handle() { @@ -144,8 +148,10 @@ public class RoundControl { 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)); } } } @@ -156,11 +162,13 @@ public class RoundControl { int totalValue = 0; for (StoneSet set : newSets) { - totalValue += set.classify(roundState.getGameSettings()).getSecond(); + totalValue += set.classify(roundState.getGameSettings()) + .getSecond(); } return totalValue == 0 - || totalValue >= roundState.getGameSettings().getInitialMeldThreshold(); + || totalValue >= roundState.getGameSettings() + .getInitialMeldThreshold(); } private void endOfTurn() { @@ -200,7 +208,8 @@ public class RoundControl { } if (!roundState.getActivePlayer().getLaidOut()) { // Player touched forbidden stones - if (!tableSetDifference(clonedTable, roundState.getTable()).isEmpty()) { + if (!tableSetDifference(clonedTable, roundState.getTable()) + .isEmpty()) { rejectMove(); return; } @@ -209,7 +218,8 @@ public class RoundControl { return; } } - Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable); + Set<Stone> tableDiff = tableDifference(roundState.getTable(), + clonedTable); roundState.setTable(clonedTable); @@ -225,7 +235,8 @@ public class RoundControl { } private void rejectMove() { - Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable); + Set<Stone> tableDiff = tableDifference(roundState.getTable(), + clonedTable); // deal penalty, reset roundState.getGameHeap().putBack(tableDiff); dealPenalty(tableDiff.size()); @@ -315,10 +326,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; diff --git a/src/jrummikub/control/SaveControl.java b/src/jrummikub/control/SaveControl.java index 458c0dc..e0589e6 100644 --- a/src/jrummikub/control/SaveControl.java +++ b/src/jrummikub/control/SaveControl.java @@ -1,12 +1,16 @@ package jrummikub.control; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import jrummikub.model.GameSettings; import jrummikub.model.GameState; import jrummikub.model.IRoundState; +import jrummikub.util.Event3; +import jrummikub.util.IEvent3; import jrummikub.util.IListener1; import jrummikub.view.IView; @@ -17,12 +21,13 @@ public class SaveControl { private GameSettings gameSettings; private GameState gameState; private IRoundState roundState; + private Event3<GameSettings, GameState, IRoundState> loadEvent = new Event3<GameSettings, GameState, IRoundState>(); /** * Creates a new SaveControl * * @param view - * the view to use + * the view to use */ public SaveControl(IView view) { view.getSaveEvent().add(new IListener1<File>() { @@ -31,13 +36,24 @@ public class SaveControl { save(file); } }); + + view.getLoadEvent().add(new IListener1<File>() { + @Override + public void handle(File file) { + load(file); + } + }); + } + + public IEvent3<GameSettings, GameState, IRoundState> getLoadEvent() { + return loadEvent; } /** * Sets the current game settings * * @param gameSettings - * the game settings + * the game settings */ public void setGameSettings(GameSettings gameSettings) { this.gameSettings = gameSettings; @@ -47,7 +63,7 @@ public class SaveControl { * Sets the current game state * * @param gameState - * the game state + * the game state */ public void setGameState(GameState gameState) { this.gameState = gameState; @@ -57,16 +73,45 @@ public class SaveControl { * Sets the current round state * * @param roundState - * the round state + * the round state */ public void setRoundState(IRoundState roundState) { this.roundState = roundState; } + private void load(File file) { + try { + ObjectInputStream stream = new ObjectInputStream( + new FileInputStream(file)); + + gameSettings = (GameSettings) stream.readObject(); + gameState = (GameState) stream.readObject(); + roundState = (IRoundState) stream.readObject(); + + stream.close(); + + if (gameState == null || gameSettings == null) { + // TODO Fehlermeldung + System.err.println("laden ging nicht"); + return; + } + + loadEvent.emit(gameSettings, gameState, roundState); + + } catch (Exception e) { + e.printStackTrace(); + } + } + private void save(File file) { + if (gameState == null || gameSettings == null) { + // TODO Menüpunkt ausgrauen + System.err.println("kein aktives Spiel"); + return; + } try { - ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream( - file)); + ObjectOutputStream stream = new ObjectOutputStream( + new FileOutputStream(file)); stream.writeObject(gameSettings); stream.writeObject(gameState); diff --git a/src/jrummikub/control/SettingsControl.java b/src/jrummikub/control/SettingsControl.java index 6da2e20..8a8fd62 100644 --- a/src/jrummikub/control/SettingsControl.java +++ b/src/jrummikub/control/SettingsControl.java @@ -333,4 +333,12 @@ public class SettingsControl { } startGameEvent.emit(settings); } + + public void abort() { + // TODO Auto-generated method stub + view.showSettingsPanel(false); + for (Connection c : connections) { + c.remove(); + } + } } diff --git a/src/jrummikub/model/StoneSet.java b/src/jrummikub/model/StoneSet.java index 0d53b52..1bb0823 100644 --- a/src/jrummikub/model/StoneSet.java +++ b/src/jrummikub/model/StoneSet.java @@ -1,5 +1,6 @@ package jrummikub.model; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -11,10 +12,12 @@ import jrummikub.util.Pair; import static jrummikub.model.StoneSet.Type.*; /** Class managing {@link Stone}s joined together to form sets */ -public class StoneSet implements Iterable<Stone>, Sizeable { +public class StoneSet implements Iterable<Stone>, Sizeable, Serializable { + private static final long serialVersionUID = -3852631195648599398L; + static final float VERTICAL_BORDER = 0.5f; static final float HORIZONTAL_BORDER = 0.125f; - private List<Stone> stones; + private ArrayList<Stone> stones; /** * Create a new single stone stone set @@ -23,7 +26,7 @@ public class StoneSet implements Iterable<Stone>, Sizeable { * single stone of the set */ public StoneSet(Stone stone) { - stones = Collections.singletonList(stone); + stones = new ArrayList<Stone>(Collections.singletonList(stone)); } /** diff --git a/src/jrummikub/model/StoneTray.java b/src/jrummikub/model/StoneTray.java index b0a824d..8806b1c 100644 --- a/src/jrummikub/model/StoneTray.java +++ b/src/jrummikub/model/StoneTray.java @@ -13,8 +13,9 @@ import jrummikub.util.Pair; * @param <E> * Type of positioned objects (must implement Sizeable) */ -@SuppressWarnings("serial") public class StoneTray<E extends Sizeable> implements IStoneTray<E> { + private static final long serialVersionUID = -6329309928640027222L; + protected HashMap<E, Pair<E, Position>> objects = new HashMap<E, Pair<E, Position>>(); /** Possible move directions in case of overlapping Stones/Sets */ diff --git a/src/jrummikub/util/Event3.java b/src/jrummikub/util/Event3.java new file mode 100644 index 0000000..a309111 --- /dev/null +++ b/src/jrummikub/util/Event3.java @@ -0,0 +1,46 @@ +package jrummikub.util; + +import java.util.HashSet; + +/** + * Simple single parameter event generator + * + * @param <T1> + * type of the first event parameter + * @param <T2> + * type of the second event parameter + */ +public class Event3<T1, T2, T3> implements IEvent3<T1, T2, T3> { + private HashSet<IListener3<T1, T2, T3>> listeners = new HashSet<IListener3<T1, T2, T3>>(); + + @Override + public Connection add(final IListener3<T1, T2, T3> listener) { + listeners.add(listener); + return new Connection() { + + @Override + public void remove() { + Event3.this.remove(listener); + } + }; + } + + @Override + public void remove(IListener3<T1, T2, T3> listener) { + listeners.remove(listener); + } + + /** + * Generate a single event + * + * @param value1 + * the first event parameter + * @param value2 + * the second event parameter + */ + public void emit(T1 value1, T2 value2, T3 value3) { + for (IListener3<T1, T2, T3> listener : listeners) { + listener.handle(value1, value2, value3); + } + } +} diff --git a/src/jrummikub/util/IEvent3.java b/src/jrummikub/util/IEvent3.java new file mode 100644 index 0000000..fd04364 --- /dev/null +++ b/src/jrummikub/util/IEvent3.java @@ -0,0 +1,28 @@ +package jrummikub.util; + +/** + * Interface for classes that can generate events having a two parameters + * + * @param <T1> + * type of the first event parameter + * @param <T2> + * type of the second event parameter + */ +public interface IEvent3<T1, T2, T3> { + /** + * Start to publish all events to a given listener + * + * @param listener + * target listener + * @return a connection to remove the listener + */ + public Connection add(IListener3<T1, T2, T3> listener); + + /** + * Stop publishing events to a given listener + * + * @param listener + * target listener + */ + public void remove(IListener3<T1, T2, T3> listener); +} diff --git a/src/jrummikub/util/IListener3.java b/src/jrummikub/util/IListener3.java new file mode 100644 index 0000000..ae1d6ce --- /dev/null +++ b/src/jrummikub/util/IListener3.java @@ -0,0 +1,22 @@ +package jrummikub.util; + +/** + * Interface for classes that can receive parameterless events having a two + * parameters + * + * @param <T1> + * type of the first event parameter + * @param <T2> + * type of the first event parameter + */ +public interface IListener3<T1, T2, T3> { + /** + * This method is called whenever a class we're listening to emits an event + * + * @param value1 + * the first event parameter + * @param value2 + * the second event parameter + */ + public void handle(T1 value1, T2 value2, T3 value3); +} |