summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mock/jrummikub/control/network/MockConnectionControl.java41
-rw-r--r--src/jrummikub/control/RoundControl.java120
-rw-r--r--src/jrummikub/control/network/ConnectionControl.java69
-rw-r--r--src/jrummikub/control/network/IConnectionControl.java14
-rw-r--r--src/jrummikub/control/network/NetworkRoundControl.java55
-rw-r--r--src/jrummikub/control/network/NetworkTurnControl.java53
-rw-r--r--src/jrummikub/control/turn/AIControl.java6
-rw-r--r--src/jrummikub/control/turn/AbstractTurnControl.java19
-rw-r--r--src/jrummikub/control/turn/HumanTurnControl.java4
-rw-r--r--src/jrummikub/control/turn/ITurnControl.java2
-rw-r--r--src/jrummikub/view/IView.java2
-rw-r--r--src/jrummikub/view/impl/PlayerPanel.java2
-rw-r--r--src/jrummikub/view/impl/View.java2
-rw-r--r--test/jrummikub/control/RoundControlTest.java4
-rw-r--r--test/jrummikub/control/network/NetworkRoundControlTest.java128
-rw-r--r--test/jrummikub/control/turn/AIControlTest.java29
-rw-r--r--test/jrummikub/control/turn/TurnControlTest.java88
17 files changed, 508 insertions, 130 deletions
diff --git a/mock/jrummikub/control/network/MockConnectionControl.java b/mock/jrummikub/control/network/MockConnectionControl.java
index 67a9c1a..fbdfb04 100644
--- a/mock/jrummikub/control/network/MockConnectionControl.java
+++ b/mock/jrummikub/control/network/MockConnectionControl.java
@@ -3,6 +3,8 @@ package jrummikub.control.network;
import java.awt.Color;
import java.util.UUID;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
import jrummikub.util.GameData;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
@@ -34,6 +36,12 @@ public class MockConnectionControl implements IConnectionControl {
/** */
public MockEvent gameStartEvent = new MockEvent();
/** */
+ public MockEvent1<ITable> tableUpdateEvent = new MockEvent1<ITable>();
+ /** */
+ public MockEvent1<ITable> turnEndEvent = new MockEvent1<ITable>();
+ /** */
+ public MockEvent1<IRoundState> turnStartEvent = new MockEvent1<IRoundState>();
+ /** */
public GameData currentGame;
/** */
public GameData offeredGame;
@@ -112,6 +120,21 @@ public class MockConnectionControl implements IConnectionControl {
}
@Override
+ public IEvent1<ITable> getTableUpdateEvent() {
+ return tableUpdateEvent;
+ }
+
+ @Override
+ public IEvent1<ITable> getTurnEndEvent() {
+ return turnEndEvent;
+ }
+
+ @Override
+ public IEvent1<IRoundState> getTurnStartEvent() {
+ return turnStartEvent;
+ }
+
+ @Override
public void offerGame(GameData data) {
offeredGame = data;
}
@@ -159,4 +182,22 @@ public class MockConnectionControl implements IConnectionControl {
// TODO Auto-generated method stub
}
+
+ @Override
+ public void updateTable(ITable table) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void endTurn(ITable table) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void startTurn(IRoundState state) {
+ // TODO Auto-generated method stub
+
+ }
}
diff --git a/src/jrummikub/control/RoundControl.java b/src/jrummikub/control/RoundControl.java
index d8435af..a19a2ab 100644
--- a/src/jrummikub/control/RoundControl.java
+++ b/src/jrummikub/control/RoundControl.java
@@ -8,6 +8,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import jrummikub.control.turn.AIControl;
+import jrummikub.control.turn.HumanTurnControl;
import jrummikub.control.turn.ITurnControl;
import jrummikub.control.turn.TurnControlFactory;
import jrummikub.control.turn.TurnMode;
@@ -16,6 +18,7 @@ import jrummikub.model.IHand;
import jrummikub.model.IPlayer;
import jrummikub.model.IRoundState;
import jrummikub.model.ITable;
+import jrummikub.model.PlayerSettings;
import jrummikub.model.Position;
import jrummikub.model.Score;
import jrummikub.model.Stone;
@@ -35,15 +38,15 @@ import jrummikub.view.IView.BottomPanelType;
* Controller that manages a single round of rummikub
*/
public class RoundControl {
- IRoundState roundState;
+ private ITurnControl turnControl;
+ protected IRoundState roundState;
private IView view;
private ITable clonedTable;
IHand clonedHand;
private Event restartRoundEvent = new Event();
+ private Event1<IRoundState> roundStateUpdateEvent = new Event1<IRoundState>();
private Event1<Score> endOfRoundEvent = new Event1<Score>();
- private Event1<ITable> tableUpdateEvent = new Event1<ITable>();
- private List<Connection> connections = new ArrayList<Connection>();
- private ITurnControl turnControl;
+ protected List<Connection> connections = new ArrayList<Connection>();
private boolean roundFinished;
private boolean lastTurnNotEnoughPoints;
private boolean lastTurnMeldError;
@@ -61,6 +64,10 @@ public class RoundControl {
this.view = view;
}
+ public IEvent1<IRoundState> getRoundStateUpdateEvent() {
+ return roundStateUpdateEvent;
+ }
+
/**
* End the round
*
@@ -70,10 +77,6 @@ public class RoundControl {
return endOfRoundEvent;
}
- public IEvent1<ITable> getTableUpdateEvent() {
- return tableUpdateEvent;
- }
-
/**
* Begin the round
*/
@@ -122,16 +125,11 @@ public class RoundControl {
clonedTable = (ITable) roundState.getTable().clone();
clonedHand = (IHand) roundState.getActivePlayer().getHand().clone();
- if (!oneHuman) {
- view.setBottomPanel(isHuman ? BottomPanelType.START_TURN_PANEL
- : BottomPanelType.COMPUTER_HAND_PANEL);
+ if (isHuman) {
+ view.setBottomPanel(oneHuman ? BottomPanelType.HUMAN_HAND_PANEL
+ : BottomPanelType.START_TURN_PANEL);
} else {
- if (!isHuman) {
- view.setBottomPanel(BottomPanelType.COMPUTER_HAND_PANEL);
- } else {
- view.setBottomPanel(BottomPanelType.HUMAN_HAND_PANEL);
- startTurn();
- }
+ view.setBottomPanel(BottomPanelType.NONHUMAN_HAND_PANEL);
}
view.getTablePanel().setStoneSets(clonedTable.clone());
@@ -141,13 +139,17 @@ public class RoundControl {
.getColor());
view.setCurrentPlayerHasLaidOut(roundState.getActivePlayer().getLaidOut());
- if (!isHuman)
+ turnControl = createTurnControl(roundState.getActivePlayer()
+ .getPlayerSettings());
+
+ boolean isAI = (turnControl instanceof AIControl);
+
+ if (isAI || (isHuman && oneHuman)) {
startTurn();
+ }
}
- private void startTurn() {
- if (turnControl != null)
- return;
+ protected void startTurn() {
boolean isHuman = roundState.getActivePlayer().getPlayerSettings()
.getType() == HUMAN;
@@ -164,34 +166,35 @@ public class RoundControl {
if (isHuman) {
view.getPlayerPanel().setEndTurnMode(turnMode);
}
- turnControl = TurnControlFactory.getFactory(
- roundState.getActivePlayer().getPlayerSettings().getType()).create();
+
turnControl.setup(new ITurnControl.TurnInfo(clonedTable, clonedHand,
roundState.getActivePlayer().getLaidOut(), turnMode), roundState
.getGameSettings(), view);
- turnControl.getEndOfTurnEvent().add(new IListener() {
+ turnControl.getEndOfTurnEvent().add(new IListener1<ITable>() {
@Override
- public void handle() {
- endOfTurn();
+ public void handle(ITable newTable) {
+ endOfTurn(newTable);
}
});
-
- turnControl.getTableUpdateEvent().add(new IListener1<ITable>() {
- @Override
- public void handle(ITable table) {
- tableUpdateEvent.emit(table);
- }
- });
-
turnControl.getRedealEvent().add(new IListener() {
@Override
public void handle() {
redeal();
}
});
+ addTurnControlListeners(turnControl);
+
turnControl.startTurn();
}
+ /** Override this */
+ protected void addTurnControlListeners(ITurnControl turnControl) {
+ }
+
+ protected ITurnControl createTurnControl(PlayerSettings playerSettings) {
+ return TurnControlFactory.getFactory(playerSettings.getType()).create();
+ }
+
void deal() {
for (int i = 0; i < roundState.getPlayerCount(); i++) {
IHand hand = roundState.getNthNextPlayer(i).getHand();
@@ -214,37 +217,44 @@ public class RoundControl {
|| totalValue >= roundState.getGameSettings().getInitialMeldThreshold();
}
- private void endOfTurn() {
+ private void endOfTurn(ITable newTable) {
+ boolean wasHuman = (turnControl instanceof HumanTurnControl);
+ boolean wasAI = (turnControl instanceof AIControl);
+
turnControl = null;
+
roundState.getActivePlayer().setHand(clonedHand);
boolean goToNextPlayer = true;
lastTurnNotEnoughPoints = false;
lastTurnMeldError = false;
if (roundState.getTurnNumber() >= 1) {
- goToNextPlayer = checkTurn();
+ goToNextPlayer = checkTurn(newTable);
}
- if (goToNextPlayer) {
+ if (goToNextPlayer || wasAI) {
nextPlayer();
} else {
- view.setBottomPanel(BottomPanelType.INVALID_TURN_PANEL);
+ if (wasHuman) {
+ view.setBottomPanel(BottomPanelType.INVALID_TURN_PANEL);
+ }
+
if (lastTurnNotEnoughPoints) {
view.setInitialMeldError(roundState.getGameSettings()
.getInitialMeldThreshold());
view.setInvalidStoneSets(tableSetDifference(roundState.getTable(),
- clonedTable));
+ newTable));
} else if (lastTurnMeldError) {
view.setInitialMeldFirstError();
- view.setInvalidStoneSets(touchedStoneSets());
+ view.setInvalidStoneSets(touchedStoneSets(newTable));
} else {
view.setStoneCollectionHidden(true);
- view.setInvalidStoneSets(invalidStoneSets());
+ view.setInvalidStoneSets(invalidStoneSets(newTable));
}
}
}
- private List<StoneSet> invalidStoneSets() {
+ private List<StoneSet> invalidStoneSets(ITable newTable) {
List<StoneSet> invalidSets = new ArrayList<StoneSet>();
- for (Pair<StoneSet, Position> set : clonedTable) {
+ for (Pair<StoneSet, Position> set : newTable) {
if (set.getFirst().isValid(roundState.getGameSettings())) {
continue;
}
@@ -253,9 +263,9 @@ public class RoundControl {
return invalidSets;
}
- private List<StoneSet> touchedStoneSets() {
+ private List<StoneSet> touchedStoneSets(ITable newTable) {
List<StoneSet> touchedSets = new ArrayList<StoneSet>();
- for (StoneSet set : tableSetDifference(roundState.getTable(), clonedTable)) {
+ for (StoneSet set : tableSetDifference(roundState.getTable(), newTable)) {
for (Stone stone : set) {
if (!roundState.getActivePlayer().getHand().contains(stone)) {
touchedSets.add(set);
@@ -293,27 +303,27 @@ public class RoundControl {
}
}
- private boolean checkTurn() {
- if (!clonedTable.isValid()) {
- rejectMove();
+ private boolean checkTurn(ITable newTable) {
+ if (!newTable.isValid()) {
+ rejectMove(newTable);
return false;
}
if (!roundState.getActivePlayer().getLaidOut()) {
// Player touched forbidden stones
- if (!tableSetDifference(clonedTable, roundState.getTable()).isEmpty()) {
- rejectMove();
+ if (!tableSetDifference(newTable, roundState.getTable()).isEmpty()) {
+ rejectMove(newTable);
lastTurnMeldError = true;
return false;
}
if (!laidOutValidPoints()) {
- rejectMove();
+ rejectMove(newTable);
lastTurnNotEnoughPoints = true;
return false;
}
}
- Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
+ Set<Stone> tableDiff = tableDifference(roundState.getTable(), newTable);
- roundState.setTable(clonedTable);
+ roundState.setTable(newTable);
if (tableDiff.isEmpty()) {
// Player hasn't made a move
@@ -327,8 +337,8 @@ public class RoundControl {
return true;
}
- private void rejectMove() {
- Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
+ private void rejectMove(ITable newTable) {
+ Set<Stone> tableDiff = tableDifference(roundState.getTable(), newTable);
// deal penalty, reset
roundState.getGameHeap().putBack(tableDiff);
dealPenalty(tableDiff.size());
diff --git a/src/jrummikub/control/network/ConnectionControl.java b/src/jrummikub/control/network/ConnectionControl.java
index 0a36ebd..acccbdc 100644
--- a/src/jrummikub/control/network/ConnectionControl.java
+++ b/src/jrummikub/control/network/ConnectionControl.java
@@ -6,6 +6,8 @@ import java.util.UUID;
import javax.swing.SwingUtilities;
import jrummikub.model.GameSettings;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
import jrummikub.util.Event;
import jrummikub.util.Event1;
import jrummikub.util.Event2;
@@ -58,6 +60,10 @@ public class ConnectionControl implements IConnectionControl {
private Event gameStartEvent = new Event();
+ private Event1<ITable> tableUpdateEvent = new Event1<ITable>();
+ private Event1<ITable> turnEndEvent = new Event1<ITable>();
+ private Event1<IRoundState> turnStartEvent = new Event1<IRoundState>();
+
private GameData currentGame;
private volatile GameData offeredGame;
@@ -145,6 +151,21 @@ public class ConnectionControl implements IConnectionControl {
}
@Override
+ public IEvent1<ITable> getTableUpdateEvent() {
+ return tableUpdateEvent;
+ }
+
+ @Override
+ public IEvent1<ITable> getTurnEndEvent() {
+ return turnEndEvent;
+ }
+
+ @Override
+ public IEvent1<IRoundState> getTurnStartEvent() {
+ return turnStartEvent;
+ }
+
+ @Override
public void offerGame(GameData data) {
offeredGame = data;
currentGame = data;
@@ -235,7 +256,6 @@ public class ConnectionControl implements IConnectionControl {
Base64.encodeObject(color, Base64.GZIP));
}
});
-
}
@Override
@@ -248,7 +268,45 @@ public class ConnectionControl implements IConnectionControl {
extension.setValue("uuid", uuid.toString());
}
});
+ }
+
+ @Override
+ public void updateTable(final ITable table) {
+ final UUID uuid = currentGame.getGameID();
+ run(new SendRunner() {
+ @Override
+ protected void addData(DefaultPacketExtension extension) {
+ extension.setValue("messageType", "table_update");
+ extension.setValue("uuid", uuid.toString());
+ extension.setValue("table", Base64.encodeObject(table, Base64.GZIP));
+ }
+ });
+ }
+
+ @Override
+ public void endTurn(final ITable table) {
+ final UUID uuid = currentGame.getGameID();
+ run(new SendRunner() {
+ @Override
+ protected void addData(DefaultPacketExtension extension) {
+ extension.setValue("messageType", "turn_end");
+ extension.setValue("uuid", uuid.toString());
+ extension.setValue("table", Base64.encodeObject(table, Base64.GZIP));
+ }
+ });
+ }
+ @Override
+ public void startTurn(final IRoundState state) {
+ final UUID uuid = currentGame.getGameID();
+ run(new SendRunner() {
+ @Override
+ protected void addData(DefaultPacketExtension extension) {
+ extension.setValue("messageType", "turn_start");
+ extension.setValue("uuid", uuid.toString());
+ extension.setValue("state", Base64.encodeObject(state, Base64.GZIP));
+ }
+ });
}
private void sendGameOffer() {
@@ -348,6 +406,15 @@ public class ConnectionControl implements IConnectionControl {
(Color) Base64.decodeToObject(extension.getValue("color")));
} else if (messageType.equals("game_start")) {
gameStartEvent.emit();
+ } else if (messageType.equals("table_update")) {
+ tableUpdateEvent.emit((ITable) Base64.decodeToObject(extension
+ .getValue("table")));
+ } else if (messageType.equals("turn_end")) {
+ turnEndEvent.emit((ITable) Base64.decodeToObject(extension
+ .getValue("table")));
+ } else if (messageType.equals("turn_start")) {
+ turnStartEvent.emit((IRoundState) Base64.decodeToObject(extension
+ .getValue("state")));
} else {
System.err.println("Received unrecognized message of type '"
+ messageType + "'");
diff --git a/src/jrummikub/control/network/IConnectionControl.java b/src/jrummikub/control/network/IConnectionControl.java
index feacf19..b329b4c 100644
--- a/src/jrummikub/control/network/IConnectionControl.java
+++ b/src/jrummikub/control/network/IConnectionControl.java
@@ -3,6 +3,8 @@ package jrummikub.control.network;
import java.awt.Color;
import java.util.UUID;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
import jrummikub.util.GameData;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
@@ -34,6 +36,12 @@ interface IConnectionControl {
public IEvent getGameStartEvent();
+ public IEvent1<ITable> getTableUpdateEvent();
+
+ public IEvent1<ITable> getTurnEndEvent();
+
+ public IEvent1<IRoundState> getTurnStartEvent();
+
public void offerGame(GameData data);
public void withdrawGame();
@@ -52,4 +60,10 @@ interface IConnectionControl {
public void startGame();
+ public void updateTable(ITable table);
+
+ public void endTurn(ITable table);
+
+ public void startTurn(IRoundState state);
+
} \ No newline at end of file
diff --git a/src/jrummikub/control/network/NetworkRoundControl.java b/src/jrummikub/control/network/NetworkRoundControl.java
new file mode 100644
index 0000000..d7de9ea
--- /dev/null
+++ b/src/jrummikub/control/network/NetworkRoundControl.java
@@ -0,0 +1,55 @@
+package jrummikub.control.network;
+
+import jrummikub.control.RoundControl;
+import jrummikub.control.turn.ITurnControl;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
+import jrummikub.model.PlayerSettings;
+import jrummikub.util.IListener1;
+import jrummikub.view.IView;
+
+public class NetworkRoundControl extends RoundControl {
+ private IConnectionControl connectionControl;
+ private boolean currentlyActive;
+
+ public NetworkRoundControl(IRoundState roundState, IView view, IConnectionControl connectionControl, boolean startActive) {
+ super(roundState, view);
+
+ this.connectionControl = connectionControl;
+ currentlyActive = startActive;
+ }
+
+ @Override
+ protected void addTurnControlListeners(ITurnControl turnControl) {
+ turnControl.getTableUpdateEvent().add(new IListener1<ITable>() {
+ @Override
+ public void handle(ITable table) {
+ connectionControl.updateTable(table);
+ }
+ });
+ }
+
+ @Override
+ protected ITurnControl createTurnControl(PlayerSettings playerSettings) {
+ switch (playerSettings.getType()) {
+ case HUMAN:
+ currentlyActive = true;
+ break;
+ case NETWORK:
+ currentlyActive = false;
+ break;
+ }
+
+ if (!currentlyActive) {
+ return new NetworkTurnControl(connectionControl);
+ }
+
+ return super.createTurnControl(playerSettings);
+ }
+
+ @Override
+ protected void startTurn() {
+ connectionControl.startTurn(roundState);
+ super.startTurn();
+ }
+}
diff --git a/src/jrummikub/control/network/NetworkTurnControl.java b/src/jrummikub/control/network/NetworkTurnControl.java
new file mode 100644
index 0000000..d80c9b3
--- /dev/null
+++ b/src/jrummikub/control/network/NetworkTurnControl.java
@@ -0,0 +1,53 @@
+package jrummikub.control.network;
+
+import jrummikub.control.turn.AbstractTurnControl;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
+import jrummikub.util.Event1;
+import jrummikub.util.IEvent1;
+import jrummikub.util.IListener1;
+
+public class NetworkTurnControl extends AbstractTurnControl {
+ private IConnectionControl connectionControl;
+ private Event1<IRoundState> stateUpdateEvent = new Event1<IRoundState>();
+
+
+ public NetworkTurnControl(IConnectionControl connectionControl) {
+ this.connectionControl = connectionControl;
+ }
+
+ public IEvent1<IRoundState> getStateUpdateEvent() {
+ return stateUpdateEvent;
+ }
+
+ @Override
+ public void doStartTurn() {
+ connections.add(connectionControl.getTableUpdateEvent().add(new IListener1<ITable>() {
+ @Override
+ public void handle(ITable table) {
+ view.getTablePanel().setStoneSets(table);
+ }
+ }));
+ connections.add(connectionControl.getTurnEndEvent().add(new IListener1<ITable>() {
+ @Override
+ public void handle(ITable table) {
+ endOfTurn(table);
+ }
+ }));
+
+ timer.startTimer();
+ }
+
+ private void endOfTurn(ITable newTable) {
+ cleanUp();
+ endOfTurnEvent.emit(newTable);
+ }
+
+ @Override
+ protected void timeOut() {
+ }
+
+ @Override
+ protected void pauseTurn() {
+ }
+}
diff --git a/src/jrummikub/control/turn/AIControl.java b/src/jrummikub/control/turn/AIControl.java
index b69d72b..ba222ea 100644
--- a/src/jrummikub/control/turn/AIControl.java
+++ b/src/jrummikub/control/turn/AIControl.java
@@ -21,7 +21,7 @@ import jrummikub.util.Pair;
*/
public class AIControl extends AbstractTurnControl {
private TurnLogic logic;
- boolean useBackgroundThread = true;
+ public static boolean useBackgroundThread = true;
long startTime;
private boolean isPaused = false;
@@ -30,7 +30,7 @@ public class AIControl extends AbstractTurnControl {
private boolean aborted = false;
@Override
- public void startTurn() {
+ protected void doStartTurn() {
timer.startTimer();
startTime = System.currentTimeMillis();
compute();
@@ -221,7 +221,7 @@ public class AIControl extends AbstractTurnControl {
return;
}
cleanUp();
- endOfTurnEvent.emit();
+ endOfTurnEvent.emit(turnInfo.getTable());
}
/**
diff --git a/src/jrummikub/control/turn/AbstractTurnControl.java b/src/jrummikub/control/turn/AbstractTurnControl.java
index fd88370..f129f24 100644
--- a/src/jrummikub/control/turn/AbstractTurnControl.java
+++ b/src/jrummikub/control/turn/AbstractTurnControl.java
@@ -19,7 +19,7 @@ import jrummikub.view.IView;
* Abstract base class for TurnControls
*/
public abstract class AbstractTurnControl implements ITurnControl {
- protected Event endOfTurnEvent = new Event();
+ protected Event1<ITable> endOfTurnEvent = new Event1<ITable>();
protected Event redealEvent = new Event();
protected Event1<ITable> tableUpdateEvent = new Event1<ITable>();
protected TurnInfo turnInfo;
@@ -27,9 +27,10 @@ public abstract class AbstractTurnControl implements ITurnControl {
protected IView view;
protected ITurnTimer timer;
protected List<Connection> connections = new ArrayList<Connection>();
+ private boolean started = false;
@Override
- public IEvent getEndOfTurnEvent() {
+ public IEvent1<ITable> getEndOfTurnEvent() {
return endOfTurnEvent;
}
@@ -37,7 +38,7 @@ public abstract class AbstractTurnControl implements ITurnControl {
public IEvent getRedealEvent() {
return redealEvent;
}
-
+
@Override
public IEvent1<ITable> getTableUpdateEvent() {
return tableUpdateEvent;
@@ -53,6 +54,18 @@ public abstract class AbstractTurnControl implements ITurnControl {
view.enablePauseMode(false);
}
+ @Override
+ public void startTurn() {
+ if (started) {
+ return;
+ }
+
+ started = true;
+ doStartTurn();
+ }
+
+ protected abstract void doStartTurn();
+
protected abstract void timeOut();
@Override
diff --git a/src/jrummikub/control/turn/HumanTurnControl.java b/src/jrummikub/control/turn/HumanTurnControl.java
index 3efad2f..51f77e4 100644
--- a/src/jrummikub/control/turn/HumanTurnControl.java
+++ b/src/jrummikub/control/turn/HumanTurnControl.java
@@ -54,7 +54,7 @@ public class HumanTurnControl extends AbstractTurnControl {
}
@Override
- public void startTurn() {
+ public void doStartTurn() {
addButtonHandlers();
addHandPanelHandlers();
@@ -449,7 +449,7 @@ public class HumanTurnControl extends AbstractTurnControl {
if (redeal) {
redealEvent.emit();
} else {
- endOfTurnEvent.emit();
+ endOfTurnEvent.emit(turnInfo.getTable());
}
}
diff --git a/src/jrummikub/control/turn/ITurnControl.java b/src/jrummikub/control/turn/ITurnControl.java
index 0039a42..1860d69 100644
--- a/src/jrummikub/control/turn/ITurnControl.java
+++ b/src/jrummikub/control/turn/ITurnControl.java
@@ -30,7 +30,7 @@ public interface ITurnControl {
*
* @return end of turn event
*/
- public IEvent getEndOfTurnEvent();
+ public IEvent1<ITable> getEndOfTurnEvent();
/**
* Emitted when the round is aborted and needs to be restarted
diff --git a/src/jrummikub/view/IView.java b/src/jrummikub/view/IView.java
index cb4846d..03bddb5 100644
--- a/src/jrummikub/view/IView.java
+++ b/src/jrummikub/view/IView.java
@@ -294,7 +294,7 @@ public interface IView {
/** */
HUMAN_HAND_PANEL,
/** */
- COMPUTER_HAND_PANEL,
+ NONHUMAN_HAND_PANEL,
/** */
WIN_PANEL
}
diff --git a/src/jrummikub/view/impl/PlayerPanel.java b/src/jrummikub/view/impl/PlayerPanel.java
index cfb858f..e557842 100644
--- a/src/jrummikub/view/impl/PlayerPanel.java
+++ b/src/jrummikub/view/impl/PlayerPanel.java
@@ -329,7 +329,7 @@ class PlayerPanel extends JPanel implements IPlayerPanel {
sortByRunsButton.setEnabled(enable);
if (!enable) {
setEndTurnMode(TurnMode.NORMAL_TURN);
- endTurnButton.setText("<html><center>Computer denkt nach");
+ endTurnButton.setText("<html><center>Spieler denkt nach");
hand.setStones(Collections.<Pair<Stone, Position>> emptyList());
handRowDownButton.setForeground(Color.GRAY);
handRowDownButton.setEnabled(false);
diff --git a/src/jrummikub/view/impl/View.java b/src/jrummikub/view/impl/View.java
index 4911de0..dee5352 100644
--- a/src/jrummikub/view/impl/View.java
+++ b/src/jrummikub/view/impl/View.java
@@ -569,7 +569,7 @@ public class View extends JFrame implements IView {
}
playerPanel.showButtons(type != BottomPanelType.START_GAME_PANEL);
- playerPanel.enableButtons(type != BottomPanelType.COMPUTER_HAND_PANEL);
+ playerPanel.enableButtons(type != BottomPanelType.NONHUMAN_HAND_PANEL);
}
@Override
diff --git a/test/jrummikub/control/RoundControlTest.java b/test/jrummikub/control/RoundControlTest.java
index 02eb3b8..d37a370 100644
--- a/test/jrummikub/control/RoundControlTest.java
+++ b/test/jrummikub/control/RoundControlTest.java
@@ -919,7 +919,7 @@ public class RoundControlTest {
testRound.startRound();
Hand hand = new Hand();
for (int i = 0; i < 6; i++) {
- hand.drop(new Stone(i / 2, RED), new Position(0, 0));
+ hand.drop(new Stone(i / 2 + 1, RED), new Position(0, 0));
}
testRoundState.players.get(0).hand = hand;
testRound.clonedHand = (IHand) hand.clone();
@@ -929,6 +929,6 @@ public class RoundControlTest {
view.playerPanel.endTurnEvent.emit();
view.startTurnEvent.emit();
}
- assertEquals( TurnMode.NORMAL_TURN, view.playerPanel.turnMode);
+ assertEquals(TurnMode.NORMAL_TURN, view.playerPanel.turnMode);
}
}
diff --git a/test/jrummikub/control/network/NetworkRoundControlTest.java b/test/jrummikub/control/network/NetworkRoundControlTest.java
new file mode 100644
index 0000000..c8eb54d
--- /dev/null
+++ b/test/jrummikub/control/network/NetworkRoundControlTest.java
@@ -0,0 +1,128 @@
+package jrummikub.control.network;
+
+import static org.junit.Assert.*;
+
+import java.awt.Color;
+
+import jrummikub.control.turn.AIControl;
+import jrummikub.model.GameSettings;
+import jrummikub.model.IPlayer;
+import jrummikub.model.IRoundState;
+import jrummikub.model.ITable;
+import jrummikub.model.PlayerSettings;
+import jrummikub.model.PlayerSettings.Type;
+import jrummikub.model.RoundState;
+import jrummikub.model.Stone;
+import jrummikub.util.IListener1;
+import jrummikub.view.MockView;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class NetworkRoundControlTest {
+ private MockConnectionControl connectionControl;
+ private MockView view;
+ private RoundState testRoundState;
+ private NetworkRoundControl testRound;
+
+ private GameSettings gameSettings;
+
+ private boolean turnStarted;
+ private boolean turnEnded;
+
+ @Before
+ public void setup() {
+ AIControl.useBackgroundThread = false;
+
+ gameSettings = new GameSettings();
+
+ gameSettings.getPlayerList().add(new PlayerSettings("Ida", Color.RED));
+ gameSettings.getPlayerList().add(
+ new PlayerSettings("Matthias", Color.YELLOW));
+ gameSettings.getPlayerList().add(new PlayerSettings("Jannis", Color.GREEN));
+ gameSettings.getPlayerList().add(new PlayerSettings("Bennet", Color.BLACK));
+
+ gameSettings.getPlayerList().get(1).setType(Type.COMPUTER);
+ gameSettings.getPlayerList().get(2).setType(Type.NETWORK);
+ gameSettings.getPlayerList().get(3).setType(Type.COMPUTER);
+ testRoundState = new RoundState(gameSettings);
+
+ view = new MockView();
+ connectionControl = new MockConnectionControl();
+ }
+
+ @Test
+ public void testHostRound() {
+ testRound = new NetworkRoundControl(testRoundState, view, connectionControl, true);
+
+ connectionControl.getTurnStartEvent().add(new IListener1<IRoundState>() {
+ @Override
+ public void handle(IRoundState roundState) {
+ assertSame(testRoundState, roundState);
+
+ turnStarted = true;
+ }
+ });
+
+ connectionControl.getTurnEndEvent().add(new IListener1<ITable>() {
+ @Override
+ public void handle(ITable table) {
+ turnEnded = true;
+ }
+ });
+
+ turnStarted = false;
+ turnEnded = false;
+
+ testRound.startRound();
+ assertTrue(turnStarted);
+ turnStarted = false;
+
+ assertEquals(4, testRoundState.getPlayerCount());
+ for (int i = 0; i < 4; ++i) {
+ IPlayer player = testRoundState.getNthPlayer(i);
+ assertSame(gameSettings.getPlayerList().get(i), player.getPlayerSettings());
+ assertEquals(gameSettings.getNumberOfStonesDealt(), player.getHand().getSize());
+ }
+ assertSame(testRoundState.getNthPlayer(0), testRoundState.getActivePlayer());
+
+ for (int i = 0; i < 4; ++i) {
+ IPlayer player = testRoundState.getNthPlayer(i);
+
+ while (player.getHand().getSize() > 1) {
+ Stone stone = player.getHand().iterator().next().getFirst();
+ player.getHand().pickUp(stone);
+ }
+ }
+
+ assertFalse(turnEnded);
+ view.playerPanel.endTurnEvent.emit();
+ assertTrue(turnEnded);
+ turnEnded = false;
+ turnStarted = false;
+
+ assertSame(testRoundState.getNthPlayer(2), testRoundState.getActivePlayer());
+
+ connectionControl.turnStartEvent.emit(testRoundState);
+ assertTrue(turnStarted);
+ turnStarted = false;
+
+ assertFalse(turnEnded);
+ connectionControl.turnEndEvent.emit(testRoundState.getTable());
+ assertTrue(turnEnded);
+ turnEnded = false;
+
+ assertSame(testRoundState.getNthPlayer(3), testRoundState.getActivePlayer());
+
+ connectionControl.turnStartEvent.emit(testRoundState);
+ assertTrue(turnStarted);
+ turnStarted = false;
+
+ assertFalse(turnEnded);
+ connectionControl.turnEndEvent.emit(testRoundState.getTable());
+ assertTrue(turnEnded);
+ turnEnded = false;
+
+ assertSame(testRoundState.getNthPlayer(0), testRoundState.getActivePlayer());
+ }
+}
diff --git a/test/jrummikub/control/turn/AIControlTest.java b/test/jrummikub/control/turn/AIControlTest.java
index 6da4b00..a8974ea 100644
--- a/test/jrummikub/control/turn/AIControlTest.java
+++ b/test/jrummikub/control/turn/AIControlTest.java
@@ -16,6 +16,7 @@ import jrummikub.model.Stone;
import jrummikub.model.StoneColor;
import jrummikub.model.Table;
import jrummikub.util.IListener;
+import jrummikub.util.IListener1;
import jrummikub.view.MockView;
import org.junit.Before;
@@ -47,10 +48,9 @@ public class AIControlTest {
turnEnded = false;
redealt = false;
- aiControl.getEndOfTurnEvent().add(new IListener() {
-
+ aiControl.getEndOfTurnEvent().add(new IListener1<ITable>() {
@Override
- public void handle() {
+ public void handle(ITable newTable) {
turnEnded = true;
}
@@ -73,12 +73,13 @@ public class AIControlTest {
/**
* @throws InterruptedException
- * if timeout
+ * if timeout
*/
@Test(timeout = 10000)
public void testTurnZeroNoRedealing() throws InterruptedException {
- aiControl.setup(new ITurnControl.TurnInfo(table, player.getHand(),
- player.getLaidOut(), TurnMode.MAY_REDEAL), gameSettings, view);
+ aiControl.setup(
+ new ITurnControl.TurnInfo(table, player.getHand(), player.getLaidOut(),
+ TurnMode.MAY_REDEAL), gameSettings, view);
aiControl.startTurn();
assertTrue(turnEnded);
assertFalse(redealt);
@@ -87,14 +88,13 @@ public class AIControlTest {
/**
* @throws InterruptedException
- * if timeout
+ * if timeout
*/
@Test(timeout = 10000)
public void testTurnZeroNotMelding() throws InterruptedException {
- aiControl
- .setup(new ITurnControl.TurnInfo(table, player.getHand(),
- player.getLaidOut(), TurnMode.INSPECT_ONLY),
- gameSettings, view);
+ aiControl.setup(
+ new ITurnControl.TurnInfo(table, player.getHand(), player.getLaidOut(),
+ TurnMode.INSPECT_ONLY), gameSettings, view);
aiControl.startTurn();
assertTrue(turnEnded);
assertFalse(redealt);
@@ -103,12 +103,13 @@ public class AIControlTest {
/**
* @throws InterruptedException
- * if timeout
+ * if timeout
*/
@Test(timeout = 10000)
public void testNormalTurnMelding() throws InterruptedException {
- aiControl.setup(new ITurnControl.TurnInfo(table, player.getHand(),
- player.getLaidOut(), TurnMode.NORMAL_TURN), gameSettings, view);
+ aiControl.setup(
+ new ITurnControl.TurnInfo(table, player.getHand(), player.getLaidOut(),
+ TurnMode.NORMAL_TURN), gameSettings, view);
aiControl.startTurn();
assertTrue(turnEnded);
assertFalse(redealt);
diff --git a/test/jrummikub/control/turn/TurnControlTest.java b/test/jrummikub/control/turn/TurnControlTest.java
index f334b29..5e3e09c 100644
--- a/test/jrummikub/control/turn/TurnControlTest.java
+++ b/test/jrummikub/control/turn/TurnControlTest.java
@@ -25,7 +25,7 @@ import jrummikub.model.StoneSet;
import jrummikub.model.Table;
import jrummikub.util.Event;
import jrummikub.util.IEvent;
-import jrummikub.util.IListener;
+import jrummikub.util.IListener1;
import jrummikub.util.Pair;
import jrummikub.view.IView.BottomPanelType;
import jrummikub.view.MockView;
@@ -133,8 +133,8 @@ public class TurnControlTest {
mockPlayer = new MockPlayer(null, null);
mockPlayer.hand = mockHand;
testControl = new HumanTurnControl(mockTimer);
- testControl.setup(new ITurnControl.TurnInfo(mockTable, mockPlayer
- .getHand(), mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN),
+ testControl.setup(new ITurnControl.TurnInfo(mockTable,
+ mockPlayer.getHand(), mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN),
new GameSettings(), mockView);
}
@@ -159,8 +159,8 @@ public class TurnControlTest {
mockHand.iterable = stones;
testControl = new HumanTurnControl(mockTimer);
- testControl.setup(new ITurnControl.TurnInfo(mockTable, mockPlayer
- .getHand(), mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN),
+ testControl.setup(new ITurnControl.TurnInfo(mockTable,
+ mockPlayer.getHand(), mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN),
new GameSettings(), mockView);
testControl.startTurn();
@@ -182,10 +182,9 @@ public class TurnControlTest {
eventFired = false;
mockTimer.timerRunning = true;
- testControl.getEndOfTurnEvent().add(new IListener() {
-
+ testControl.getEndOfTurnEvent().add(new IListener1<ITable>() {
@Override
- public void handle() {
+ public void handle(ITable newTable) {
eventFired = true;
}
});
@@ -205,10 +204,9 @@ public class TurnControlTest {
eventFired = false;
mockTimer.timerRunning = true;
- testControl.getEndOfTurnEvent().add(new IListener() {
-
+ testControl.getEndOfTurnEvent().add(new IListener1<ITable>() {
@Override
- public void handle() {
+ public void handle(ITable newTable) {
eventFired = true;
}
});
@@ -292,8 +290,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(redJoker, true);
mockView.handPanel.stoneClickEvent.emit(blackJoker, true);
- mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(
- blackJoker, true);
+ mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(blackJoker,
+ true);
assertCollection(Arrays.asList(redJoker, blackJoker));
}
@@ -309,8 +307,7 @@ public class TurnControlTest {
mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(redJoker,
true);
- mockView.tablePanel.stoneCollectionPanel.setClickEvent.emit(redJoker,
- true);
+ mockView.tablePanel.stoneCollectionPanel.setClickEvent.emit(redJoker, true);
assertCollection(new ArrayList<Stone>());
}
@@ -408,8 +405,8 @@ public class TurnControlTest {
testControl.startTurn();
Stone stone4 = new Stone(4, StoneColor.RED);
- StoneSet set1 = new StoneSet(Arrays.asList(redOne, redTwo, redThree,
- stone4));
+ StoneSet set1 = new StoneSet(
+ Arrays.asList(redOne, redTwo, redThree, stone4));
mockTable.findStoneSet.put(redOne, set1);
mockTable.findStoneSet.put(redThree, set1);
@@ -576,15 +573,15 @@ public class TurnControlTest {
public void testAddLeft() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(new ITurnControl.TurnInfo(table,
- mockPlayer.getHand(), mockPlayer.getLaidOut(),
- TurnMode.NORMAL_TURN), new GameSettings(), mockView);
+ turnControl.setup(new ITurnControl.TurnInfo(table, mockPlayer.getHand(),
+ mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN), new GameSettings(),
+ mockView);
turnControl.startTurn();
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -683,14 +680,14 @@ public class TurnControlTest {
public void testAddRight() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(new ITurnControl.TurnInfo(table,
- mockPlayer.getHand(), mockPlayer.getLaidOut(),
- TurnMode.NORMAL_TURN), new GameSettings(), mockView);
+ turnControl.setup(new ITurnControl.TurnInfo(table, mockPlayer.getHand(),
+ mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN), new GameSettings(),
+ mockView);
turnControl.startTurn();
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -789,14 +786,14 @@ public class TurnControlTest {
public void testAddNewSet() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(new ITurnControl.TurnInfo(table,
- mockPlayer.getHand(), mockPlayer.getLaidOut(),
- TurnMode.NORMAL_TURN), new GameSettings(), mockView);
+ turnControl.setup(new ITurnControl.TurnInfo(table, mockPlayer.getHand(),
+ mockPlayer.getLaidOut(), TurnMode.NORMAL_TURN), new GameSettings(),
+ mockView);
turnControl.startTurn();
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -887,8 +884,8 @@ public class TurnControlTest {
List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones);
- Collections.sort(stones,
- new HumanTurnControl.HandStonePositionComparator());
+ Collections
+ .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13);
@@ -936,8 +933,8 @@ public class TurnControlTest {
List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones);
- Collections.sort(stones,
- new HumanTurnControl.HandStonePositionComparator());
+ Collections
+ .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13);
@@ -977,8 +974,8 @@ public class TurnControlTest {
assertCollection(new ArrayList<Stone>());
- Set<Stone> expected = new HashSet<Stone>(Arrays.asList(redJoker,
- blackJoker));
+ Set<Stone> expected = new HashSet<Stone>(
+ Arrays.asList(redJoker, blackJoker));
assertEquals(expected, mockHand.pickups);
Set<Stone> handStones = new HashSet<Stone>();
@@ -1005,8 +1002,7 @@ public class TurnControlTest {
assertCollection(Arrays.asList(blackJoker));
- Set<Stone> expected = new HashSet<Stone>(Arrays.asList(redJoker,
- black13));
+ Set<Stone> expected = new HashSet<Stone>(Arrays.asList(redJoker, black13));
assertEquals(expected, mockHand.pickups);
Set<Stone> handStones = new HashSet<Stone>();