Fixed a bunch of network synchronization bugs

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@510 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Matthias Schiffer 2011-06-20 06:41:15 +02:00
parent 74d8205f30
commit 0c3eb9a283
15 changed files with 137 additions and 94 deletions

View file

@ -3,15 +3,18 @@ package jrummikub.control.network;
import java.awt.Color; import java.awt.Color;
import java.util.UUID; import java.util.UUID;
import jrummikub.model.IHand;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.GameData; import jrummikub.util.GameData;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IEvent2; import jrummikub.util.IEvent2;
import jrummikub.util.IEvent3;
import jrummikub.util.MockEvent; import jrummikub.util.MockEvent;
import jrummikub.util.MockEvent1; import jrummikub.util.MockEvent1;
import jrummikub.util.MockEvent2; import jrummikub.util.MockEvent2;
import jrummikub.util.MockEvent3;
import jrummikub.view.LoginError; import jrummikub.view.LoginError;
/** */ /** */
@ -41,7 +44,7 @@ public class MockConnectionControl implements IConnectionControl {
/** */ /** */
public MockEvent1<ITable> tableUpdateEvent = new MockEvent1<ITable>(); public MockEvent1<ITable> tableUpdateEvent = new MockEvent1<ITable>();
/** */ /** */
public MockEvent1<ITable> turnEndEvent = new MockEvent1<ITable>(); public MockEvent3<IHand, ITable, ITable> turnEndEvent = new MockEvent3<IHand, ITable, ITable>();
/** */ /** */
public MockEvent1<IRoundState> turnStartEvent = new MockEvent1<IRoundState>(); public MockEvent1<IRoundState> turnStartEvent = new MockEvent1<IRoundState>();
/** */ /** */
@ -137,7 +140,7 @@ public class MockConnectionControl implements IConnectionControl {
} }
@Override @Override
public IEvent1<ITable> getTurnEndEvent() { public IEvent3<IHand, ITable, ITable> getTurnEndEvent() {
return turnEndEvent; return turnEndEvent;
} }
@ -202,7 +205,7 @@ public class MockConnectionControl implements IConnectionControl {
} }
@Override @Override
public void endTurn(ITable table) { public void endTurn(IHand oldHand, ITable oldTable, ITable newTable) {
turnEnded = true; turnEnded = true;
} }

View file

@ -18,7 +18,7 @@ import jrummikub.model.IHand;
import jrummikub.model.IPlayer; import jrummikub.model.IPlayer;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.model.PlayerSettings; import jrummikub.model.PlayerSettings.Type;
import jrummikub.model.Position; import jrummikub.model.Position;
import jrummikub.model.Score; import jrummikub.model.Score;
import jrummikub.model.Stone; import jrummikub.model.Stone;
@ -29,7 +29,7 @@ import jrummikub.util.Event1;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IListener; import jrummikub.util.IListener;
import jrummikub.util.IListener1; import jrummikub.util.IListener3;
import jrummikub.util.Pair; import jrummikub.util.Pair;
import jrummikub.view.IView; import jrummikub.view.IView;
import jrummikub.view.IView.BottomPanelType; import jrummikub.view.IView.BottomPanelType;
@ -153,14 +153,11 @@ public class RoundControl {
.getType() == HUMAN; .getType() == HUMAN;
boolean oneHuman = roundState.getGameSettings().oneHuman(); boolean oneHuman = roundState.getGameSettings().oneHuman();
clonedTable = (ITable) roundState.getTable().clone();
clonedHand = (IHand) roundState.getActivePlayer().getHand().clone();
if (isHuman && !oneHuman) { if (isHuman && !oneHuman) {
view.setBottomPanel(BottomPanelType.START_TURN_PANEL); view.setBottomPanel(BottomPanelType.START_TURN_PANEL);
} }
view.getTablePanel().setStoneSets(clonedTable.clone()); view.getTablePanel().setStoneSets(roundState.getTable().clone());
view.setCurrentPlayerName(roundState.getActivePlayer().getPlayerSettings() view.setCurrentPlayerName(roundState.getActivePlayer().getPlayerSettings()
.getName()); .getName());
view.setCurrentPlayerColor(roundState.getActivePlayer().getPlayerSettings() view.setCurrentPlayerColor(roundState.getActivePlayer().getPlayerSettings()
@ -168,7 +165,7 @@ public class RoundControl {
view.setCurrentPlayerHasLaidOut(roundState.getActivePlayer().getLaidOut()); view.setCurrentPlayerHasLaidOut(roundState.getActivePlayer().getLaidOut());
turnControl = createTurnControl(roundState.getActivePlayer() turnControl = createTurnControl(roundState.getActivePlayer()
.getPlayerSettings()); .getPlayerSettings().getType());
} }
protected void startTurn() { protected void startTurn() {
@ -184,6 +181,11 @@ public class RoundControl {
TurnMode turnMode = TurnMode.NORMAL_TURN; TurnMode turnMode = TurnMode.NORMAL_TURN;
view.getTablePanel().setStoneSets(roundState.getTable().clone());
clonedTable = (ITable) roundState.getTable().clone();
clonedHand = (IHand) roundState.getActivePlayer().getHand().clone();
if (roundState.getTurnNumber() < 1) { if (roundState.getTurnNumber() < 1) {
view.setStoneCollectionHidden(true); view.setStoneCollectionHidden(true);
turnMode = TurnMode.INSPECT_ONLY; turnMode = TurnMode.INSPECT_ONLY;
@ -199,12 +201,20 @@ public class RoundControl {
turnControl.setup(new ITurnControl.TurnInfo(clonedTable, clonedHand, turnControl.setup(new ITurnControl.TurnInfo(clonedTable, clonedHand,
roundState.getActivePlayer().getLaidOut(), turnMode), roundState roundState.getActivePlayer().getLaidOut(), turnMode), roundState
.getGameSettings(), view); .getGameSettings(), view);
turnControl.getEndOfTurnEvent().add(new IListener1<ITable>() { turnControl.getEndOfTurnEvent().add(
@Override new IListener3<IHand, ITable, ITable>() {
public void handle(ITable newTable) { @Override
endOfTurn(newTable); public void handle(IHand oldHand, ITable oldTable, ITable newTable) {
} if (oldHand == null) {
}); oldHand = roundState.getActivePlayer().getHand();
}
if (oldTable == null) {
oldTable = roundState.getTable();
}
endOfTurn(oldHand, oldTable, newTable);
}
});
turnControl.getRedealEvent().add(new IListener() { turnControl.getRedealEvent().add(new IListener() {
@Override @Override
public void handle() { public void handle() {
@ -233,8 +243,8 @@ public class RoundControl {
protected void addTurnControlListeners(ITurnControl turnControl) { protected void addTurnControlListeners(ITurnControl turnControl) {
} }
protected ITurnControl createTurnControl(PlayerSettings playerSettings) { protected ITurnControl createTurnControl(Type type) {
return TurnControlFactory.getFactory(playerSettings.getType()).create(); return TurnControlFactory.getFactory(type).create();
} }
void deal() { void deal() {
@ -248,9 +258,8 @@ public class RoundControl {
view.getSidePanel().setHeapSize(roundState.getGameHeap().getSize()); view.getSidePanel().setHeapSize(roundState.getGameHeap().getSize());
} }
private boolean laidOutValidPoints() { private boolean laidOutValidPoints(ITable oldTable, ITable newTable) {
List<StoneSet> newSets = tableSetDifference(roundState.getTable(), List<StoneSet> newSets = tableSetDifference(oldTable, newTable);
clonedTable);
int totalValue = 0; int totalValue = 0;
for (StoneSet set : newSets) { for (StoneSet set : newSets) {
@ -261,10 +270,12 @@ public class RoundControl {
|| totalValue >= roundState.getGameSettings().getInitialMeldThreshold(); || totalValue >= roundState.getGameSettings().getInitialMeldThreshold();
} }
protected void endOfTurn(ITable newTable) { protected void endOfTurn(IHand oldHand, ITable oldTable, ITable newTable) {
boolean wasHuman = (turnControl instanceof HumanTurnControl); boolean wasHuman = (turnControl instanceof HumanTurnControl);
boolean wasAI = (turnControl instanceof AIControl); boolean wasAI = (turnControl instanceof AIControl);
view.setBottomPanel(BottomPanelType.NONHUMAN_HAND_PANEL);
turnControl = null; turnControl = null;
roundState.getActivePlayer().setLastTurnInvalid(false); roundState.getActivePlayer().setLastTurnInvalid(false);
@ -278,7 +289,7 @@ public class RoundControl {
lastTurnNotEnoughPoints = false; lastTurnNotEnoughPoints = false;
lastTurnMeldError = false; lastTurnMeldError = false;
if (roundState.getTurnNumber() >= 1) { if (roundState.getTurnNumber() >= 1) {
goToNextPlayer = checkTurn(newTable); goToNextPlayer = checkTurn(oldTable, newTable);
} }
if (goToNextPlayer || wasAI) { if (goToNextPlayer || wasAI) {
nextPlayer(); nextPlayer();
@ -290,11 +301,10 @@ public class RoundControl {
if (lastTurnNotEnoughPoints) { if (lastTurnNotEnoughPoints) {
view.setInitialMeldError(roundState.getGameSettings() view.setInitialMeldError(roundState.getGameSettings()
.getInitialMeldThreshold()); .getInitialMeldThreshold());
view.setInvalidStoneSets(tableSetDifference(roundState.getTable(), view.setInvalidStoneSets(tableSetDifference(oldTable, newTable));
newTable));
} else if (lastTurnMeldError) { } else if (lastTurnMeldError) {
view.setInitialMeldFirstError(); view.setInitialMeldFirstError();
view.setInvalidStoneSets(touchedStoneSets(newTable)); view.setInvalidStoneSets(touchedStoneSets(oldHand, oldTable, newTable));
} else { } else {
view.setStoneCollectionHidden(true); view.setStoneCollectionHidden(true);
view.setInvalidStoneSets(invalidStoneSets(newTable)); view.setInvalidStoneSets(invalidStoneSets(newTable));
@ -313,11 +323,12 @@ public class RoundControl {
return invalidSets; return invalidSets;
} }
private List<StoneSet> touchedStoneSets(ITable newTable) { private List<StoneSet> touchedStoneSets(IHand oldHand, ITable oldTable,
ITable newTable) {
List<StoneSet> touchedSets = new ArrayList<StoneSet>(); List<StoneSet> touchedSets = new ArrayList<StoneSet>();
for (StoneSet set : tableSetDifference(roundState.getTable(), newTable)) { for (StoneSet set : tableSetDifference(oldTable, newTable)) {
for (Stone stone : set) { for (Stone stone : set) {
if (!roundState.getActivePlayer().getHand().contains(stone)) { if (!oldHand.contains(stone)) {
touchedSets.add(set); touchedSets.add(set);
break; break;
} }
@ -353,25 +364,25 @@ public class RoundControl {
} }
} }
private boolean checkTurn(ITable newTable) { private boolean checkTurn(ITable oldTable, ITable newTable) {
if (!newTable.isValid()) { if (!newTable.isValid()) {
rejectMove(newTable); rejectMove(oldTable, newTable);
return false; return false;
} }
if (!roundState.getActivePlayer().getLaidOut()) { if (!roundState.getActivePlayer().getLaidOut()) {
// Player touched forbidden stones // Player touched forbidden stones
if (!tableSetDifference(newTable, roundState.getTable()).isEmpty()) { if (!tableSetDifference(newTable, oldTable).isEmpty()) {
rejectMove(newTable); rejectMove(oldTable, newTable);
lastTurnMeldError = true; lastTurnMeldError = true;
return false; return false;
} }
if (!laidOutValidPoints()) { if (!laidOutValidPoints(oldTable, newTable)) {
rejectMove(newTable); rejectMove(oldTable, newTable);
lastTurnNotEnoughPoints = true; lastTurnNotEnoughPoints = true;
return false; return false;
} }
} }
Set<Stone> tableDiff = tableDifference(roundState.getTable(), newTable); Set<Stone> tableDiff = tableDifference(oldTable, newTable);
roundState.setTable(newTable); roundState.setTable(newTable);
@ -387,8 +398,8 @@ public class RoundControl {
return true; return true;
} }
private void rejectMove(ITable newTable) { private void rejectMove(ITable oldTable, ITable newTable) {
Set<Stone> tableDiff = tableDifference(roundState.getTable(), newTable); Set<Stone> tableDiff = tableDifference(oldTable, newTable);
// deal penalty, reset // deal penalty, reset
roundState.getGameHeap().putBack(tableDiff); roundState.getGameHeap().putBack(tableDiff);
roundState.getActivePlayer().setLastTurnInvalid(true); roundState.getActivePlayer().setLastTurnInvalid(true);

View file

@ -6,15 +6,18 @@ import java.util.UUID;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import jrummikub.model.GameSettings; import jrummikub.model.GameSettings;
import jrummikub.model.IHand;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.Event; import jrummikub.util.Event;
import jrummikub.util.Event1; import jrummikub.util.Event1;
import jrummikub.util.Event2; import jrummikub.util.Event2;
import jrummikub.util.Event3;
import jrummikub.util.GameData; import jrummikub.util.GameData;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IEvent2; import jrummikub.util.IEvent2;
import jrummikub.util.IEvent3;
import jrummikub.util.LoginData; import jrummikub.util.LoginData;
import jrummikub.view.LoginError; import jrummikub.view.LoginError;
@ -63,7 +66,7 @@ public class ConnectionControl implements IConnectionControl {
private Event roundStartEvent = new Event(); private Event roundStartEvent = new Event();
private Event1<ITable> tableUpdateEvent = new Event1<ITable>(); private Event1<ITable> tableUpdateEvent = new Event1<ITable>();
private Event1<ITable> turnEndEvent = new Event1<ITable>(); private Event3<IHand, ITable, ITable> turnEndEvent = new Event3<IHand, ITable, ITable>();
private Event1<IRoundState> turnStartEvent = new Event1<IRoundState>(); private Event1<IRoundState> turnStartEvent = new Event1<IRoundState>();
private GameData currentGame; private GameData currentGame;
@ -163,7 +166,7 @@ public class ConnectionControl implements IConnectionControl {
} }
@Override @Override
public IEvent1<ITable> getTurnEndEvent() { public IEvent3<IHand, ITable, ITable> getTurnEndEvent() {
return turnEndEvent; return turnEndEvent;
} }
@ -302,14 +305,20 @@ public class ConnectionControl implements IConnectionControl {
} }
@Override @Override
public void endTurn(final ITable table) { public void endTurn(final IHand oldHand, final ITable oldTable,
final ITable newTable) {
final UUID uuid = currentGame.getGameID(); final UUID uuid = currentGame.getGameID();
run(new SendRunner() { run(new SendRunner() {
@Override @Override
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "turn_end"); extension.setValue("messageType", "turn_end");
extension.setValue("uuid", uuid.toString()); extension.setValue("uuid", uuid.toString());
extension.setValue("table", Base64.encodeObject(table, Base64.GZIP)); extension.setValue("old_hand",
Base64.encodeObject(oldHand, Base64.GZIP));
extension.setValue("old_table",
Base64.encodeObject(oldTable, Base64.GZIP));
extension.setValue("new_table",
Base64.encodeObject(newTable, Base64.GZIP));
} }
}); });
} }
@ -438,8 +447,10 @@ public class ConnectionControl implements IConnectionControl {
tableUpdateEvent.emit((ITable) Base64.decodeToObject(extension tableUpdateEvent.emit((ITable) Base64.decodeToObject(extension
.getValue("table"))); .getValue("table")));
} else if (messageType.equals("turn_end")) { } else if (messageType.equals("turn_end")) {
turnEndEvent.emit((ITable) Base64.decodeToObject(extension turnEndEvent.emit(
.getValue("table"))); (IHand) Base64.decodeToObject(extension.getValue("old_hand")),
(ITable) Base64.decodeToObject(extension.getValue("old_table")),
(ITable) Base64.decodeToObject(extension.getValue("new_table")));
} else if (messageType.equals("turn_start")) { } else if (messageType.equals("turn_start")) {
turnStartEvent.emit((IRoundState) Base64.decodeToObject(extension turnStartEvent.emit((IRoundState) Base64.decodeToObject(extension
.getValue("state"))); .getValue("state")));

View file

@ -3,12 +3,14 @@ package jrummikub.control.network;
import java.awt.Color; import java.awt.Color;
import java.util.UUID; import java.util.UUID;
import jrummikub.model.IHand;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.GameData; import jrummikub.util.GameData;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IEvent2; import jrummikub.util.IEvent2;
import jrummikub.util.IEvent3;
import jrummikub.view.LoginError; import jrummikub.view.LoginError;
interface IConnectionControl { interface IConnectionControl {
@ -41,7 +43,7 @@ interface IConnectionControl {
public IEvent1<ITable> getTableUpdateEvent(); public IEvent1<ITable> getTableUpdateEvent();
public IEvent1<ITable> getTurnEndEvent(); public IEvent3<IHand, ITable, ITable> getTurnEndEvent();
public IEvent1<IRoundState> getTurnStartEvent(); public IEvent1<IRoundState> getTurnStartEvent();
@ -67,7 +69,7 @@ interface IConnectionControl {
public void updateTable(ITable table); public void updateTable(ITable table);
public void endTurn(ITable table); public void endTurn(IHand oldHand, ITable oldTable, ITable newTable);
public void startTurn(IRoundState state); public void startTurn(IRoundState state);
} }

View file

@ -2,9 +2,10 @@ package jrummikub.control.network;
import jrummikub.control.RoundControl; import jrummikub.control.RoundControl;
import jrummikub.control.turn.ITurnControl; import jrummikub.control.turn.ITurnControl;
import jrummikub.model.IHand;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.model.PlayerSettings; import jrummikub.model.PlayerSettings.Type;
import jrummikub.util.IListener1; import jrummikub.util.IListener1;
import jrummikub.view.IView; import jrummikub.view.IView;
@ -23,7 +24,8 @@ public class NetworkRoundControl extends RoundControl {
new IListener1<IRoundState>() { new IListener1<IRoundState>() {
@Override @Override
public void handle(IRoundState state) { public void handle(IRoundState state) {
NetworkControl.fixGameSettings(state.getGameSettings(), connectionControl.getNickname()); NetworkControl.fixGameSettings(state.getGameSettings(),
connectionControl.getNickname());
setRoundState(state); setRoundState(state);
startTurn(); startTurn();
@ -42,8 +44,8 @@ public class NetworkRoundControl extends RoundControl {
} }
@Override @Override
protected ITurnControl createTurnControl(PlayerSettings playerSettings) { protected ITurnControl createTurnControl(Type type) {
switch (playerSettings.getType()) { switch (type) {
case HUMAN: case HUMAN:
currentlyActive = true; currentlyActive = true;
break; break;
@ -56,7 +58,7 @@ public class NetworkRoundControl extends RoundControl {
return new NetworkTurnControl(connectionControl); return new NetworkTurnControl(connectionControl);
} }
return super.createTurnControl(playerSettings); return super.createTurnControl(type);
} }
@Override @Override
@ -71,11 +73,11 @@ public class NetworkRoundControl extends RoundControl {
} }
@Override @Override
protected void endOfTurn(ITable newTable) { protected void endOfTurn(IHand oldHand, ITable oldTable, ITable newTable) {
if (currentlyActive) { if (currentlyActive) {
connectionControl.endTurn(newTable); connectionControl.endTurn(oldHand, oldTable, newTable);
} }
super.endOfTurn(newTable); super.endOfTurn(oldHand, oldTable, newTable);
} }
} }

View file

@ -1,52 +1,56 @@
package jrummikub.control.network; package jrummikub.control.network;
import jrummikub.control.turn.AbstractTurnControl; import jrummikub.control.turn.AbstractTurnControl;
import jrummikub.model.IHand;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.Event1; import jrummikub.util.Event1;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IListener1; import jrummikub.util.IListener1;
import jrummikub.util.IListener3;
public class NetworkTurnControl extends AbstractTurnControl { public class NetworkTurnControl extends AbstractTurnControl {
private IConnectionControl connectionControl; private IConnectionControl connectionControl;
private Event1<IRoundState> stateUpdateEvent = new Event1<IRoundState>(); private Event1<IRoundState> stateUpdateEvent = new Event1<IRoundState>();
public NetworkTurnControl(IConnectionControl connectionControl) { public NetworkTurnControl(IConnectionControl connectionControl) {
this.connectionControl = connectionControl; this.connectionControl = connectionControl;
} }
public IEvent1<IRoundState> getStateUpdateEvent() { public IEvent1<IRoundState> getStateUpdateEvent() {
return stateUpdateEvent; return stateUpdateEvent;
} }
@Override @Override
public void doStartTurn() { public void doStartTurn() {
connections.add(connectionControl.getTableUpdateEvent().add(new IListener1<ITable>() { connections.add(connectionControl.getTableUpdateEvent().add(
@Override new IListener1<ITable>() {
public void handle(ITable table) { @Override
view.getTablePanel().setStoneSets(table); public void handle(ITable table) {
} view.getTablePanel().setStoneSets(table);
})); }
connections.add(connectionControl.getTurnEndEvent().add(new IListener1<ITable>() { }));
@Override connections.add(connectionControl.getTurnEndEvent().add(
public void handle(ITable table) { new IListener3<IHand, ITable, ITable>() {
endOfTurn(table); @Override
} public void handle(IHand oldHand, ITable oldTable, ITable newTable) {
})); endOfTurn(oldHand, oldTable, newTable);
}
}));
timer.startTimer(); timer.startTimer();
} }
private void endOfTurn(ITable newTable) { private void endOfTurn(IHand oldHand, ITable oldTable, ITable newTable) {
cleanUp(); cleanUp();
endOfTurnEvent.emit(newTable);
endOfTurnEvent.emit(oldHand, oldTable, newTable);
} }
@Override @Override
protected void timeOut() { protected void timeOut() {
} }
@Override @Override
protected void pauseTurn() { protected void pauseTurn() {
} }

View file

@ -225,7 +225,7 @@ public class AIControl extends AbstractTurnControl {
return; return;
} }
cleanUp(); cleanUp();
endOfTurnEvent.emit(turnInfo.getTable()); endOfTurnEvent.emit(null, null, turnInfo.getTable());
} }
/** /**

View file

@ -6,12 +6,15 @@ import java.util.List;
import jrummikub.control.ITurnTimer; import jrummikub.control.ITurnTimer;
import jrummikub.control.TurnTimer; import jrummikub.control.TurnTimer;
import jrummikub.model.GameSettings; import jrummikub.model.GameSettings;
import jrummikub.model.IHand;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.Connection; import jrummikub.util.Connection;
import jrummikub.util.Event; import jrummikub.util.Event;
import jrummikub.util.Event1; import jrummikub.util.Event1;
import jrummikub.util.Event3;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IEvent3;
import jrummikub.util.IListener; import jrummikub.util.IListener;
import jrummikub.view.IView; import jrummikub.view.IView;
@ -19,7 +22,7 @@ import jrummikub.view.IView;
* Abstract base class for TurnControls * Abstract base class for TurnControls
*/ */
public abstract class AbstractTurnControl implements ITurnControl { public abstract class AbstractTurnControl implements ITurnControl {
protected Event1<ITable> endOfTurnEvent = new Event1<ITable>(); protected Event3<IHand, ITable, ITable> endOfTurnEvent = new Event3<IHand, ITable, ITable>();
protected Event redealEvent = new Event(); protected Event redealEvent = new Event();
protected Event1<ITable> tableUpdateEvent = new Event1<ITable>(); protected Event1<ITable> tableUpdateEvent = new Event1<ITable>();
protected TurnInfo turnInfo; protected TurnInfo turnInfo;
@ -30,7 +33,7 @@ public abstract class AbstractTurnControl implements ITurnControl {
private boolean started = false; private boolean started = false;
@Override @Override
public IEvent1<ITable> getEndOfTurnEvent() { public IEvent3<IHand, ITable, ITable> getEndOfTurnEvent() {
return endOfTurnEvent; return endOfTurnEvent;
} }

View file

@ -448,7 +448,7 @@ public class HumanTurnControl extends AbstractTurnControl {
if (redeal) { if (redeal) {
redealEvent.emit(); redealEvent.emit();
} else { } else {
endOfTurnEvent.emit(turnInfo.getTable()); endOfTurnEvent.emit(null, null, turnInfo.getTable());
} }
} }

View file

@ -5,6 +5,7 @@ import jrummikub.model.IHand;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IEvent1; import jrummikub.util.IEvent1;
import jrummikub.util.IEvent3;
import jrummikub.view.IView; import jrummikub.view.IView;
/** /**
@ -30,7 +31,7 @@ public interface ITurnControl {
* *
* @return end of turn event * @return end of turn event
*/ */
public IEvent1<ITable> getEndOfTurnEvent(); public IEvent3<IHand, ITable, ITable> getEndOfTurnEvent();
/** /**
* Emitted when the round is aborted and needs to be restarted * Emitted when the round is aborted and needs to be restarted

View file

@ -48,7 +48,10 @@ public class GameControlTest {
@Test @Test
public void testEndOfRound() { public void testEndOfRound() {
gameControl.startGame(); gameControl.startGame();
// Manipulate first players hand, to allow player1 to win
view.startTurnEvent.emit();
// Manipulate first player's hand, to allow player1 to win
IHand playerHand = gameControl.roundControl.clonedHand; IHand playerHand = gameControl.roundControl.clonedHand;
for (Pair<Stone, Position> entry : playerHand.clone()) { for (Pair<Stone, Position> entry : playerHand.clone()) {
playerHand.pickUp(entry.getFirst()); playerHand.pickUp(entry.getFirst());
@ -61,7 +64,6 @@ public class GameControlTest {
playerHand.drop(stone3, new Position(0, 0)); playerHand.drop(stone3, new Position(0, 0));
// Done setting up first players hand // Done setting up first players hand
view.startTurnEvent.emit();
view.playerPanel.endTurnEvent.emit(); view.playerPanel.endTurnEvent.emit();
view.startTurnEvent.emit(); view.startTurnEvent.emit();
view.playerPanel.endTurnEvent.emit(); view.playerPanel.endTurnEvent.emit();

View file

@ -899,12 +899,12 @@ public class RoundControlTest {
@Test @Test
public void testRedealDisallowed() { public void testRedealDisallowed() {
testRound.startRound(); testRound.startRound();
view.startTurnEvent.emit();
Hand hand = new Hand(); Hand hand = new Hand();
hand.drop(new Stone(1, RED), new Position(0, 0)); hand.drop(new Stone(1, RED), new Position(0, 0));
hand.drop(new Stone(1, BLACK), new Position(0, 0)); hand.drop(new Stone(1, BLACK), new Position(0, 0));
hand.drop(new Stone(1, BLUE), new Position(0, 0)); hand.drop(new Stone(1, BLUE), new Position(0, 0));
testRound.clonedHand = hand; testRound.clonedHand = hand;
view.startTurnEvent.emit();
assertEquals(TurnMode.INSPECT_ONLY, view.playerPanel.turnMode); assertEquals(TurnMode.INSPECT_ONLY, view.playerPanel.turnMode);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
view.playerPanel.endTurnEvent.emit(); view.playerPanel.endTurnEvent.emit();

View file

@ -103,7 +103,8 @@ public class NetworkRoundControlTest {
connectionControl.turnStartEvent.emit(testRoundState); connectionControl.turnStartEvent.emit(testRoundState);
assertFalse(connectionControl.turnEnded); assertFalse(connectionControl.turnEnded);
connectionControl.turnEndEvent.emit(testRoundState.getTable()); connectionControl.turnEndEvent.emit(testRoundState.getActivePlayer()
.getHand(), testRoundState.getTable(), testRoundState.getTable());
assertSame(testRoundState.getNthPlayer(3), testRoundState.getActivePlayer()); assertSame(testRoundState.getNthPlayer(3), testRoundState.getActivePlayer());
assertFalse(connectionControl.turnStarted); assertFalse(connectionControl.turnStarted);
@ -111,7 +112,8 @@ public class NetworkRoundControlTest {
connectionControl.turnStartEvent.emit(testRoundState); connectionControl.turnStartEvent.emit(testRoundState);
assertFalse(connectionControl.turnEnded); assertFalse(connectionControl.turnEnded);
connectionControl.turnEndEvent.emit(testRoundState.getTable()); connectionControl.turnEndEvent.emit(testRoundState.getActivePlayer()
.getHand(), testRoundState.getTable(), testRoundState.getTable());
assertSame(testRoundState.getNthPlayer(0), testRoundState.getActivePlayer()); assertSame(testRoundState.getNthPlayer(0), testRoundState.getActivePlayer());
assertFalse(connectionControl.turnStarted); assertFalse(connectionControl.turnStarted);
@ -144,7 +146,8 @@ public class NetworkRoundControlTest {
connectionControl.turnStartEvent.emit(testRoundState); connectionControl.turnStartEvent.emit(testRoundState);
assertFalse(connectionControl.turnEnded); assertFalse(connectionControl.turnEnded);
connectionControl.turnEndEvent.emit(testRoundState.getTable()); connectionControl.turnEndEvent.emit(testRoundState.getActivePlayer()
.getHand(), testRoundState.getTable(), testRoundState.getTable());
assertSame(testRoundState.getNthPlayer(1), testRoundState.getActivePlayer()); assertSame(testRoundState.getNthPlayer(1), testRoundState.getActivePlayer());
assertFalse(connectionControl.turnStarted); assertFalse(connectionControl.turnStarted);
@ -152,7 +155,8 @@ public class NetworkRoundControlTest {
connectionControl.turnStartEvent.emit(testRoundState); connectionControl.turnStartEvent.emit(testRoundState);
assertFalse(connectionControl.turnEnded); assertFalse(connectionControl.turnEnded);
connectionControl.turnEndEvent.emit(testRoundState.getTable()); connectionControl.turnEndEvent.emit(testRoundState.getActivePlayer()
.getHand(), testRoundState.getTable(), testRoundState.getTable());
assertSame(testRoundState.getNthPlayer(2), testRoundState.getActivePlayer()); assertSame(testRoundState.getNthPlayer(2), testRoundState.getActivePlayer());
assertFalse(connectionControl.turnStarted); assertFalse(connectionControl.turnStarted);

View file

@ -16,7 +16,7 @@ import jrummikub.model.Stone;
import jrummikub.model.StoneColor; import jrummikub.model.StoneColor;
import jrummikub.model.Table; import jrummikub.model.Table;
import jrummikub.util.IListener; import jrummikub.util.IListener;
import jrummikub.util.IListener1; import jrummikub.util.IListener3;
import jrummikub.view.MockView; import jrummikub.view.MockView;
import org.junit.Before; import org.junit.Before;
@ -48,9 +48,9 @@ public class AIControlTest {
turnEnded = false; turnEnded = false;
redealt = false; redealt = false;
aiControl.getEndOfTurnEvent().add(new IListener1<ITable>() { aiControl.getEndOfTurnEvent().add(new IListener3<IHand, ITable, ITable>() {
@Override @Override
public void handle(ITable newTable) { public void handle(IHand oldHand, ITable oldTable, ITable newTable) {
turnEnded = true; turnEnded = true;
} }

View file

@ -25,7 +25,7 @@ import jrummikub.model.StoneSet;
import jrummikub.model.Table; import jrummikub.model.Table;
import jrummikub.util.Event; import jrummikub.util.Event;
import jrummikub.util.IEvent; import jrummikub.util.IEvent;
import jrummikub.util.IListener1; import jrummikub.util.IListener3;
import jrummikub.util.Pair; import jrummikub.util.Pair;
import jrummikub.view.IView.BottomPanelType; import jrummikub.view.IView.BottomPanelType;
import jrummikub.view.MockView; import jrummikub.view.MockView;
@ -182,9 +182,9 @@ public class TurnControlTest {
eventFired = false; eventFired = false;
mockTimer.timerRunning = true; mockTimer.timerRunning = true;
testControl.getEndOfTurnEvent().add(new IListener1<ITable>() { testControl.getEndOfTurnEvent().add(new IListener3<IHand, ITable, ITable>() {
@Override @Override
public void handle(ITable newTable) { public void handle(IHand oldHand, ITable oldTable, ITable newTable) {
eventFired = true; eventFired = true;
} }
}); });
@ -204,9 +204,9 @@ public class TurnControlTest {
eventFired = false; eventFired = false;
mockTimer.timerRunning = true; mockTimer.timerRunning = true;
testControl.getEndOfTurnEvent().add(new IListener1<ITable>() { testControl.getEndOfTurnEvent().add(new IListener3<IHand, ITable, ITable>() {
@Override @Override
public void handle(ITable newTable) { public void handle(IHand oldHand, ITable oldTable, ITable newTable) {
eventFired = true; eventFired = true;
} }
}); });