summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jrummikub/control/ApplicationControl.java46
-rw-r--r--src/jrummikub/control/GameControl.java31
-rw-r--r--src/jrummikub/control/RoundControl.java53
-rw-r--r--src/jrummikub/control/SaveControl.java57
-rw-r--r--src/jrummikub/control/SettingsControl.java8
-rw-r--r--src/jrummikub/model/StoneSet.java9
-rw-r--r--src/jrummikub/model/StoneTray.java3
-rw-r--r--src/jrummikub/util/Event3.java46
-rw-r--r--src/jrummikub/util/IEvent3.java28
-rw-r--r--src/jrummikub/util/IListener3.java22
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);
+}