Fix many comments, fix tests, fix complexity
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@462 72836036-5685-4462-b002-a69064685172
This commit is contained in:
parent
823ef9d4fe
commit
bc835d499f
8 changed files with 265 additions and 101 deletions
|
@ -67,6 +67,8 @@ public class MockView implements IView {
|
||||||
public MockEvent endPauseEvent = new MockEvent();
|
public MockEvent endPauseEvent = new MockEvent();
|
||||||
/** */
|
/** */
|
||||||
public MockEvent networkGameEvent = new MockEvent();
|
public MockEvent networkGameEvent = new MockEvent();
|
||||||
|
/** */
|
||||||
|
public MockEvent acknowledgeInvalidEvent = new MockEvent();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MockTablePanel getTablePanel() {
|
public MockTablePanel getTablePanel() {
|
||||||
|
@ -100,8 +102,7 @@ public class MockView implements IView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IEvent getAcknowledgeInvalidEvent() {
|
public IEvent getAcknowledgeInvalidEvent() {
|
||||||
// TODO Auto-generated method stub
|
return acknowledgeInvalidEvent;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,19 +222,19 @@ public class MockView implements IView {
|
||||||
@Override
|
@Override
|
||||||
public void setInitialMeldError(int points) {
|
public void setInitialMeldError(int points) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStoneCollectionHidden(boolean enable) {
|
public void setStoneCollectionHidden(boolean enable) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInitialMeldFirstError() {
|
public void setInitialMeldFirstError() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ import jrummikub.model.StoneColor;
|
||||||
import jrummikub.model.StoneSet;
|
import jrummikub.model.StoneSet;
|
||||||
import jrummikub.util.Pair;
|
import jrummikub.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logic behind the ai turns
|
||||||
|
*/
|
||||||
public class TurnLogic {
|
public class TurnLogic {
|
||||||
private GameSettings settings;
|
private GameSettings settings;
|
||||||
private int stoneCount;
|
private int stoneCount;
|
||||||
|
@ -264,13 +267,15 @@ public class TurnLogic {
|
||||||
|
|
||||||
public boolean update(HashSet<Integer> changes) throws Contradiction {
|
public boolean update(HashSet<Integer> changes) throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
changed |= updateRuns(changes);
|
changed |= updateRightRuns(changes);
|
||||||
changed |= updateGroups(changes);
|
changed |= updateLeftRuns(changes);
|
||||||
|
changed |= updateRightGroups(changes);
|
||||||
|
changed |= updateLeftGroups(changes);
|
||||||
changed |= checkState();
|
changed |= checkState();
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean updateRuns(HashSet<Integer> changes)
|
public boolean updateRightRuns(HashSet<Integer> changes)
|
||||||
throws Contradiction {
|
throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
HashSet<Integer> relevantChanges = new HashSet<Integer>(leftRun);
|
HashSet<Integer> relevantChanges = new HashSet<Integer>(leftRun);
|
||||||
|
@ -288,7 +293,13 @@ public class TurnLogic {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
relevantChanges = new HashSet<Integer>(rightRun);
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateLeftRuns(HashSet<Integer> changes)
|
||||||
|
throws Contradiction {
|
||||||
|
boolean changed = false;
|
||||||
|
HashSet<Integer> relevantChanges = new HashSet<Integer>(rightRun);
|
||||||
relevantChanges.retainAll(changes);
|
relevantChanges.retainAll(changes);
|
||||||
for (int i : relevantChanges) {
|
for (int i : relevantChanges) {
|
||||||
StoneState other = top.stones.get(i);
|
StoneState other = top.stones.get(i);
|
||||||
|
@ -306,7 +317,7 @@ public class TurnLogic {
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean updateGroups(HashSet<Integer> changes)
|
public boolean updateRightGroups(HashSet<Integer> changes)
|
||||||
throws Contradiction {
|
throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
HashSet<Integer> relevantChanges = new HashSet<Integer>(leftGroup);
|
HashSet<Integer> relevantChanges = new HashSet<Integer>(leftGroup);
|
||||||
|
@ -325,6 +336,13 @@ public class TurnLogic {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateLeftGroups(HashSet<Integer> changes)
|
||||||
|
throws Contradiction {
|
||||||
|
boolean changed = false;
|
||||||
|
HashSet<Integer> relevantChanges = new HashSet<Integer>(leftGroup);
|
||||||
relevantChanges = new HashSet<Integer>(rightGroup);
|
relevantChanges = new HashSet<Integer>(rightGroup);
|
||||||
relevantChanges.retainAll(changes);
|
relevantChanges.retainAll(changes);
|
||||||
for (int i : relevantChanges) {
|
for (int i : relevantChanges) {
|
||||||
|
@ -345,6 +363,7 @@ public class TurnLogic {
|
||||||
|
|
||||||
public boolean checkState() throws Contradiction {
|
public boolean checkState() throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
|
|
||||||
if (onTable == Boolean.FALSE) {
|
if (onTable == Boolean.FALSE) {
|
||||||
if (leftRun.size() + rightRun.size() + leftGroup.size()
|
if (leftRun.size() + rightRun.size() + leftGroup.size()
|
||||||
+ rightGroup.size() != 0) {
|
+ rightGroup.size() != 0) {
|
||||||
|
@ -357,6 +376,23 @@ public class TurnLogic {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changed |= checkSetTypeKnown();
|
||||||
|
|
||||||
|
changed |= checkLonelyStone();
|
||||||
|
|
||||||
|
changed |= checkNeighborStoneNeeded();
|
||||||
|
|
||||||
|
changed |= checkStoneCanBeOnTable();
|
||||||
|
|
||||||
|
checkGroupRunExclusive();
|
||||||
|
|
||||||
|
changed |= checkJoker();
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSetTypeKnown() {
|
||||||
|
boolean changed = false;
|
||||||
if (!(leftGroup.contains(null) || rightGroup.contains(null))) {
|
if (!(leftGroup.contains(null) || rightGroup.contains(null))) {
|
||||||
changed |= leftRun.retainAll(Arrays.asList((Integer) null))
|
changed |= leftRun.retainAll(Arrays.asList((Integer) null))
|
||||||
| rightRun.retainAll(Arrays.asList((Integer) null));
|
| rightRun.retainAll(Arrays.asList((Integer) null));
|
||||||
|
@ -365,7 +401,11 @@ public class TurnLogic {
|
||||||
changed |= leftGroup.retainAll(Arrays.asList((Integer) null))
|
changed |= leftGroup.retainAll(Arrays.asList((Integer) null))
|
||||||
| rightGroup.retainAll(Arrays.asList((Integer) null));
|
| rightGroup.retainAll(Arrays.asList((Integer) null));
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkLonelyStone() {
|
||||||
|
boolean changed = false;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(
|
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(
|
||||||
leftGroup, rightGroup, leftRun, rightRun, leftGroup,
|
leftGroup, rightGroup, leftRun, rightRun, leftGroup,
|
||||||
|
@ -376,7 +416,11 @@ public class TurnLogic {
|
||||||
changed |= sets.get(i + 3).remove(null);
|
changed |= sets.get(i + 3).remove(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkNeighborStoneNeeded() {
|
||||||
|
boolean changed = false;
|
||||||
if (isSingleNonNullSet(leftRun)
|
if (isSingleNonNullSet(leftRun)
|
||||||
&& isNullSet(top.stones.get(leftRun.iterator().next()).leftRun)) {
|
&& isNullSet(top.stones.get(leftRun.iterator().next()).leftRun)) {
|
||||||
changed |= rightRun.remove(null);
|
changed |= rightRun.remove(null);
|
||||||
|
@ -394,7 +438,11 @@ public class TurnLogic {
|
||||||
&& isNullSet(top.stones.get(rightGroup.iterator().next()).rightGroup)) {
|
&& isNullSet(top.stones.get(rightGroup.iterator().next()).rightGroup)) {
|
||||||
changed |= leftGroup.remove(null);
|
changed |= leftGroup.remove(null);
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkStoneCanBeOnTable() throws Contradiction {
|
||||||
|
boolean changed = false;
|
||||||
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|
||||||
|| leftRun.isEmpty() || rightRun.isEmpty()) {
|
|| leftRun.isEmpty() || rightRun.isEmpty()) {
|
||||||
if (onTable == Boolean.TRUE) {
|
if (onTable == Boolean.TRUE) {
|
||||||
|
@ -409,15 +457,14 @@ public class TurnLogic {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkGroupRunExclusive() throws Contradiction {
|
||||||
if ((isSingleNonNullSet(leftGroup) || isSingleNonNullSet(rightGroup))
|
if ((isSingleNonNullSet(leftGroup) || isSingleNonNullSet(rightGroup))
|
||||||
&& (isSingleNonNullSet(leftRun) || isSingleNonNullSet(rightRun))) {
|
&& (isSingleNonNullSet(leftRun) || isSingleNonNullSet(rightRun))) {
|
||||||
throw new Contradiction();
|
throw new Contradiction();
|
||||||
}
|
}
|
||||||
|
|
||||||
changed |= checkJoker();
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkJoker() {
|
private boolean checkJoker() {
|
||||||
|
@ -425,16 +472,22 @@ public class TurnLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSolved() {
|
public boolean isSolved() {
|
||||||
|
boolean solved = false;
|
||||||
if (onTable == Boolean.FALSE) {
|
if (onTable == Boolean.FALSE) {
|
||||||
return true;
|
return solved;
|
||||||
}
|
}
|
||||||
if (onTable == null || color == null || value == null) {
|
if (onTable == null || color == null || value == null) {
|
||||||
return false;
|
return solved;
|
||||||
}
|
}
|
||||||
if (leftRun.size() > 1 || rightRun.size() > 1
|
if (leftRun.size() > 1 || rightRun.size() > 1
|
||||||
|| leftGroup.size() > 1 || rightGroup.size() > 1) {
|
|| leftGroup.size() > 1 || rightGroup.size() > 1) {
|
||||||
return false;
|
return solved;
|
||||||
}
|
}
|
||||||
|
solved = bothGoupAndRun();
|
||||||
|
return solved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean bothGoupAndRun() {
|
||||||
if (!((isNullSet(leftRun) && isNullSet(rightRun)) || (isNullSet(leftGroup) && isNullSet(rightGroup)))) {
|
if (!((isNullSet(leftRun) && isNullSet(rightRun)) || (isNullSet(leftGroup) && isNullSet(rightGroup)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -467,6 +520,16 @@ public class TurnLogic {
|
||||||
return i.size() == 1 && !i.contains(null);
|
return i.size() == 1 && !i.contains(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new turn logic
|
||||||
|
*
|
||||||
|
* @param settings
|
||||||
|
* the game settings
|
||||||
|
* @param tableStones
|
||||||
|
* all stones on the table
|
||||||
|
* @param handStones
|
||||||
|
* all stones on the hand
|
||||||
|
*/
|
||||||
public TurnLogic(GameSettings settings, Collection<Stone> tableStones,
|
public TurnLogic(GameSettings settings, Collection<Stone> tableStones,
|
||||||
Collection<Stone> handStones) {
|
Collection<Stone> handStones) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -517,6 +580,9 @@ public class TurnLogic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include initial meld threshold into turn logic
|
||||||
|
*/
|
||||||
public void needIntialMeldThreshold() {
|
public void needIntialMeldThreshold() {
|
||||||
neededPoints = settings.getInitialMeldThreshold();
|
neededPoints = settings.getInitialMeldThreshold();
|
||||||
}
|
}
|
||||||
|
@ -542,10 +608,18 @@ public class TurnLogic {
|
||||||
top = stack.get(stack.size() - 1);
|
top = stack.get(stack.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aborts currently running solve call
|
||||||
|
*/
|
||||||
public void abort() {
|
public void abort() {
|
||||||
abort = true;
|
abort = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the found stones and create output sets
|
||||||
|
*
|
||||||
|
* @return output sets to put on table
|
||||||
|
*/
|
||||||
public List<StoneSet> getResult() {
|
public List<StoneSet> getResult() {
|
||||||
State result = bestState;
|
State result = bestState;
|
||||||
|
|
||||||
|
@ -574,10 +648,14 @@ public class TurnLogic {
|
||||||
outputSets.add(new StoneSet(setStones));
|
outputSets.add(new StoneSet(setStones));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputSets;
|
return outputSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves next state on stack while not aborted
|
||||||
|
*
|
||||||
|
* @return solved
|
||||||
|
*/
|
||||||
public boolean solve() {
|
public boolean solve() {
|
||||||
if (top.isSolved()) {
|
if (top.isSolved()) {
|
||||||
pop();
|
pop();
|
||||||
|
@ -601,6 +679,11 @@ public class TurnLogic {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizes the solution found as long as stopped from control
|
||||||
|
*
|
||||||
|
* @return score of found solution
|
||||||
|
*/
|
||||||
public double optimize() {
|
public double optimize() {
|
||||||
while (!autoAbort && solve()) {
|
while (!autoAbort && solve()) {
|
||||||
neededScore = top.getScore();
|
neededScore = top.getScore();
|
||||||
|
@ -613,77 +696,37 @@ public class TurnLogic {
|
||||||
StoneState stone = top.stones.get(i);
|
StoneState stone = top.stones.get(i);
|
||||||
if (stone.onTable == null) {
|
if (stone.onTable == null) {
|
||||||
replace();
|
replace();
|
||||||
State newState = new State(top);
|
branchOnHand(i);
|
||||||
newState.stones.get(i).onTable = false;
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
State altState = new State(top);
|
|
||||||
altState.stones.get(i).onTable = true;
|
|
||||||
altState.changedStones.add(i);
|
|
||||||
pushes(altState, newState);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.leftRun.size() > 1) {
|
if (stone.leftRun.size() > 1) {
|
||||||
replace();
|
replace();
|
||||||
for (Integer id : stone.leftRun) {
|
branchLeftRun(i, stone);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).leftRun.clear();
|
|
||||||
newState.stones.get(i).leftRun.add(id);
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.rightRun.size() > 1) {
|
if (stone.rightRun.size() > 1) {
|
||||||
replace();
|
replace();
|
||||||
for (Integer id : stone.rightRun) {
|
branchRightRun(i, stone);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).rightRun.clear();
|
|
||||||
newState.stones.get(i).rightRun.add(id);
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.leftGroup.size() > 1) {
|
if (stone.leftGroup.size() > 1) {
|
||||||
replace();
|
replace();
|
||||||
for (Integer id : stone.leftGroup) {
|
branchLeftGroup(i, stone);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).leftGroup.clear();
|
|
||||||
newState.stones.get(i).leftGroup.add(id);
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.rightGroup.size() > 1) {
|
if (stone.rightGroup.size() > 1) {
|
||||||
replace();
|
replace();
|
||||||
for (Integer id : stone.rightGroup) {
|
branchRightGroup(i, stone);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).rightGroup.clear();
|
|
||||||
newState.stones.get(i).rightGroup.add(id);
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.color == null) {
|
if (stone.color == null) {
|
||||||
replace();
|
replace();
|
||||||
for (StoneColor color : stoneColors) {
|
branchColor(i);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).color = color;
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stone.value == null) {
|
if (stone.value == null) {
|
||||||
replace();
|
replace();
|
||||||
for (int value = 1; value <= settings.getHighestValue(); value++) {
|
branchValue(i);
|
||||||
State newState = new State(top);
|
|
||||||
newState.stones.get(i).value = value;
|
|
||||||
newState.changedStones.add(i);
|
|
||||||
pushes(newState);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,11 +734,81 @@ public class TurnLogic {
|
||||||
throw new Error("Internal AI error");
|
throw new Error("Internal AI error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void branchValue(int i) {
|
||||||
|
for (int value = 1; value <= settings.getHighestValue(); value++) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).value = value;
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchColor(int i) {
|
||||||
|
for (StoneColor color : stoneColors) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).color = color;
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchRightGroup(int i, StoneState stone) {
|
||||||
|
for (Integer id : stone.rightGroup) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).rightGroup.clear();
|
||||||
|
newState.stones.get(i).rightGroup.add(id);
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchLeftGroup(int i, StoneState stone) {
|
||||||
|
for (Integer id : stone.leftGroup) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).leftGroup.clear();
|
||||||
|
newState.stones.get(i).leftGroup.add(id);
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchRightRun(int i, StoneState stone) {
|
||||||
|
for (Integer id : stone.rightRun) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).rightRun.clear();
|
||||||
|
newState.stones.get(i).rightRun.add(id);
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchLeftRun(int i, StoneState stone) {
|
||||||
|
for (Integer id : stone.leftRun) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).leftRun.clear();
|
||||||
|
newState.stones.get(i).leftRun.add(id);
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
pushes(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void branchOnHand(int i) {
|
||||||
|
State newState = new State(top);
|
||||||
|
newState.stones.get(i).onTable = false;
|
||||||
|
newState.changedStones.add(i);
|
||||||
|
State altState = new State(top);
|
||||||
|
altState.stones.get(i).onTable = true;
|
||||||
|
altState.changedStones.add(i);
|
||||||
|
pushes(altState, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort as soon as a solution is found
|
||||||
|
*/
|
||||||
public void autoAbort() {
|
public void autoAbort() {
|
||||||
if (bestState != null) {
|
if (bestState != null) {
|
||||||
abort = true;
|
abort = true;
|
||||||
}
|
}
|
||||||
autoAbort = true;
|
autoAbort = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,10 +228,12 @@ public class RoundControl {
|
||||||
} else {
|
} else {
|
||||||
List<Stone> markedStones = new ArrayList<Stone>();
|
List<Stone> markedStones = new ArrayList<Stone>();
|
||||||
for (Pair<StoneSet, Position> set : clonedTable) {
|
for (Pair<StoneSet, Position> set : clonedTable) {
|
||||||
if (!set.getFirst().isValid(roundState.getGameSettings())) {
|
if (set.getFirst().isValid(roundState.getGameSettings())) {
|
||||||
for (Stone stone : set.getFirst()) {
|
continue;
|
||||||
markedStones.add(stone);
|
}
|
||||||
}
|
for (Stone stone : set.getFirst()) {
|
||||||
|
markedStones.add(stone);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.setStoneCollectionHidden(true);
|
view.setStoneCollectionHidden(true);
|
||||||
|
@ -401,8 +403,8 @@ public class RoundControl {
|
||||||
.getGameSettings());
|
.getGameSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
bestScore = updateBestScore(bestScore, -stonePoints,
|
bestScore = updateBestScore(bestScore, -stonePoints, playerHand
|
||||||
playerHand.getSize());
|
.getSize());
|
||||||
|
|
||||||
points.add(-stonePoints);
|
points.add(-stonePoints);
|
||||||
pointSum += stonePoints;
|
pointSum += stonePoints;
|
||||||
|
@ -424,8 +426,8 @@ public class RoundControl {
|
||||||
private static Pair<Integer, Integer> updateBestScore(
|
private static Pair<Integer, Integer> updateBestScore(
|
||||||
Pair<Integer, Integer> bestScore, int stonePoints, int size) {
|
Pair<Integer, Integer> bestScore, int stonePoints, int size) {
|
||||||
if (bestScore.getFirst() == stonePoints) {
|
if (bestScore.getFirst() == stonePoints) {
|
||||||
return new Pair<Integer, Integer>(stonePoints, Math.min(
|
return new Pair<Integer, Integer>(stonePoints, Math.min(bestScore
|
||||||
bestScore.getSecond(), size));
|
.getSecond(), size));
|
||||||
} else if (bestScore.getFirst() < stonePoints) {
|
} else if (bestScore.getFirst() < stonePoints) {
|
||||||
return new Pair<Integer, Integer>(stonePoints, size);
|
return new Pair<Integer, Integer>(stonePoints, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,6 +299,11 @@ class ConnectionControl implements IConnectionControl {
|
||||||
|
|
||||||
String messageType = extension.getValue("messageType");
|
String messageType = extension.getValue("messageType");
|
||||||
|
|
||||||
|
handleMessageTypes(extension, sender, messageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMessageTypes(DefaultPacketExtension extension,
|
||||||
|
String sender, String messageType) {
|
||||||
if (messageType.equals("game_offer")) {
|
if (messageType.equals("game_offer")) {
|
||||||
UUID uuid = UUID.fromString(extension.getValue("uuid"));
|
UUID uuid = UUID.fromString(extension.getValue("uuid"));
|
||||||
GameSettings settings = (GameSettings) Base64
|
GameSettings settings = (GameSettings) Base64
|
||||||
|
|
|
@ -10,8 +10,21 @@ import jrummikub.util.IListener1;
|
||||||
import jrummikub.view.ISettingsPanel.SettingsMode;
|
import jrummikub.view.ISettingsPanel.SettingsMode;
|
||||||
import jrummikub.view.IView;
|
import jrummikub.view.IView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control for joining a network game
|
||||||
|
*/
|
||||||
public class GameJoinControl extends AbstractGameBeginControl {
|
public class GameJoinControl extends AbstractGameBeginControl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new game join control
|
||||||
|
*
|
||||||
|
* @param connectionControl
|
||||||
|
* the current connection control for events and messages
|
||||||
|
* @param gameData
|
||||||
|
* the game data for settings, game id
|
||||||
|
* @param view
|
||||||
|
* the view
|
||||||
|
*/
|
||||||
public GameJoinControl(final IConnectionControl connectionControl,
|
public GameJoinControl(final IConnectionControl connectionControl,
|
||||||
final GameData gameData, final IView view) {
|
final GameData gameData, final IView view) {
|
||||||
super(connectionControl, view, gameData, SettingsMode.NETWORK_JOIN);
|
super(connectionControl, view, gameData, SettingsMode.NETWORK_JOIN);
|
||||||
|
@ -54,6 +67,9 @@ public class GameJoinControl extends AbstractGameBeginControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the join control and sets the settings panel in game join mode
|
||||||
|
*/
|
||||||
public void startGameJoin() {
|
public void startGameJoin() {
|
||||||
view.showSettingsPanel(true);
|
view.showSettingsPanel(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,21 @@ import jrummikub.util.IListener1;
|
||||||
import jrummikub.view.ISettingsPanel.SettingsMode;
|
import jrummikub.view.ISettingsPanel.SettingsMode;
|
||||||
import jrummikub.view.IView;
|
import jrummikub.view.IView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control for network game host
|
||||||
|
*/
|
||||||
public class GameOfferControl extends AbstractGameBeginControl {
|
public class GameOfferControl extends AbstractGameBeginControl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new game offer control
|
||||||
|
*
|
||||||
|
* @param connectionControl
|
||||||
|
* for events (listening and handling)
|
||||||
|
* @param settings
|
||||||
|
* the game settings for player list, colors, names
|
||||||
|
* @param view
|
||||||
|
* the view
|
||||||
|
*/
|
||||||
public GameOfferControl(final IConnectionControl connectionControl,
|
public GameOfferControl(final IConnectionControl connectionControl,
|
||||||
final GameSettings settings, final IView view) {
|
final GameSettings settings, final IView view) {
|
||||||
super(connectionControl, view,
|
super(connectionControl, view,
|
||||||
|
@ -57,6 +70,10 @@ public class GameOfferControl extends AbstractGameBeginControl {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sends the game offer and starts the settings panel for host using network
|
||||||
|
* offer type
|
||||||
|
*/
|
||||||
public void startGameOffer() {
|
public void startGameOffer() {
|
||||||
connectionControl.offerGame(gameData);
|
connectionControl.offerGame(gameData);
|
||||||
|
|
||||||
|
|
|
@ -44,26 +44,27 @@ public class NetworkControl {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
connectionControl = new ConnectionControl(loginData);
|
connectionControl = new ConnectionControl(loginData);
|
||||||
|
|
||||||
|
addConnectionSetupListeners(loginData, view);
|
||||||
addConnectionControlListeners(loginData, view);
|
addConnectionControlListeners(loginData, view);
|
||||||
|
|
||||||
connections.add(view.getGameListPanel().getJoinEvent()
|
connections.add(view.getGameListPanel().getJoinEvent().add(
|
||||||
.add(new IListener1<GameData>() {
|
new IListener1<GameData>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameData gameData) {
|
public void handle(GameData gameData) {
|
||||||
join(gameData);
|
join(gameData);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
connections.add(view.getGameListPanel().getOpenNewGameEvent()
|
connections.add(view.getGameListPanel().getOpenNewGameEvent().add(
|
||||||
.add(new IListener() {
|
new IListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handle() {
|
public void handle() {
|
||||||
createSettingsControl();
|
createSettingsControl();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
connections.add(view.getGameListPanel().getCancelEvent()
|
connections.add(view.getGameListPanel().getCancelEvent().add(
|
||||||
.add(new IListener() {
|
new IListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handle() {
|
public void handle() {
|
||||||
abort();
|
abort();
|
||||||
|
@ -87,25 +88,6 @@ public class NetworkControl {
|
||||||
*/
|
*/
|
||||||
public void addConnectionControlListeners(final LoginData loginData,
|
public void addConnectionControlListeners(final LoginData loginData,
|
||||||
final IView view) {
|
final IView view) {
|
||||||
connections.add(connectionControl.getConnectedEvent().add(
|
|
||||||
new IListener() {
|
|
||||||
@Override
|
|
||||||
public void handle() {
|
|
||||||
view.getGameListPanel().setChannelName(
|
|
||||||
loginData.getChannelName());
|
|
||||||
view.showGameListPanel(true);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
connections.add(connectionControl.getConnectionFailedEvent().add(
|
|
||||||
new IListener() {
|
|
||||||
@Override
|
|
||||||
public void handle() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
connections.add(connectionControl.getGameOfferEvent().add(
|
connections.add(connectionControl.getGameOfferEvent().add(
|
||||||
new IListener1<GameData>() {
|
new IListener1<GameData>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,6 +131,28 @@ public class NetworkControl {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addConnectionSetupListeners(final LoginData loginData,
|
||||||
|
final IView view) {
|
||||||
|
connections.add(connectionControl.getConnectedEvent().add(
|
||||||
|
new IListener() {
|
||||||
|
@Override
|
||||||
|
public void handle() {
|
||||||
|
view.getGameListPanel().setChannelName(
|
||||||
|
loginData.getChannelName());
|
||||||
|
view.showGameListPanel(true);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
connections.add(connectionControl.getConnectionFailedEvent().add(
|
||||||
|
new IListener() {
|
||||||
|
@Override
|
||||||
|
public void handle() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private void updateGameList() {
|
private void updateGameList() {
|
||||||
List<GameData> gameList = new ArrayList<GameData>();
|
List<GameData> gameList = new ArrayList<GameData>();
|
||||||
|
|
||||||
|
@ -220,8 +224,8 @@ public class NetworkControl {
|
||||||
}
|
}
|
||||||
view.showGameListPanel(false);
|
view.showGameListPanel(false);
|
||||||
|
|
||||||
settingsControl = new NetworkSettingsControl(
|
settingsControl = new NetworkSettingsControl(connectionControl
|
||||||
connectionControl.getNickname(), view, new GameSettings());
|
.getNickname(), view, new GameSettings());
|
||||||
settingsControl.getOfferGameEvent().add(new IListener1<GameSettings>() {
|
settingsControl.getOfferGameEvent().add(new IListener1<GameSettings>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSettings settings) {
|
public void handle(GameSettings settings) {
|
||||||
|
|
|
@ -301,6 +301,7 @@ public class RoundControlTest {
|
||||||
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
||||||
|
|
||||||
view.playerPanel.endTurnEvent.emit();
|
view.playerPanel.endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
||||||
.getLaidOut());
|
.getLaidOut());
|
||||||
assertEquals(2, roundState.getTable().getSize());
|
assertEquals(2, roundState.getTable().getSize());
|
||||||
|
@ -375,6 +376,7 @@ public class RoundControlTest {
|
||||||
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
||||||
|
|
||||||
view.playerPanel.endTurnEvent.emit();
|
view.playerPanel.endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
||||||
.getLaidOut());
|
.getLaidOut());
|
||||||
assertEquals(2, roundState.getTable().getSize());
|
assertEquals(2, roundState.getTable().getSize());
|
||||||
|
@ -439,6 +441,7 @@ public class RoundControlTest {
|
||||||
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
view.tablePanel.clickEvent.emit(new Position(0, 0));
|
||||||
|
|
||||||
view.playerPanel.endTurnEvent.emit();
|
view.playerPanel.endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
assertFalse(roundState.getNthNextPlayer(roundState.getPlayerCount() - 1)
|
||||||
.getLaidOut());
|
.getLaidOut());
|
||||||
assertEquals(2, roundState.getTable().getSize());
|
assertEquals(2, roundState.getTable().getSize());
|
||||||
|
@ -579,6 +582,7 @@ public class RoundControlTest {
|
||||||
testTable.drop(new StoneSet(stone), new Position(0, 0));
|
testTable.drop(new StoneSet(stone), new Position(0, 0));
|
||||||
resetTurnStart();
|
resetTurnStart();
|
||||||
view.getPlayerPanel().endTurnEvent.emit();
|
view.getPlayerPanel().endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
|
|
||||||
assertNull(testRoundState.setTable);
|
assertNull(testRoundState.setTable);
|
||||||
assertEquals(1, testRoundState.activePlayer);
|
assertEquals(1, testRoundState.activePlayer);
|
||||||
|
@ -628,6 +632,7 @@ public class RoundControlTest {
|
||||||
assertSame(BottomPanelType.HUMAN_HAND_PANEL, view.bottomPanelType);
|
assertSame(BottomPanelType.HUMAN_HAND_PANEL, view.bottomPanelType);
|
||||||
resetTurnStart();
|
resetTurnStart();
|
||||||
view.getPlayerPanel().endTurnEvent.emit();
|
view.getPlayerPanel().endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
|
|
||||||
assertNull(testRoundState.setTable);
|
assertNull(testRoundState.setTable);
|
||||||
assertEquals(14 + 3, testRoundState.players.get(0).hand.getSize());
|
assertEquals(14 + 3, testRoundState.players.get(0).hand.getSize());
|
||||||
|
@ -907,6 +912,7 @@ public class RoundControlTest {
|
||||||
view.startTurnEvent.emit();
|
view.startTurnEvent.emit();
|
||||||
assertFalse(view.tablePanel.clickEvent.listeners.isEmpty());
|
assertFalse(view.tablePanel.clickEvent.listeners.isEmpty());
|
||||||
view.playerPanel.endTurnEvent.emit();
|
view.playerPanel.endTurnEvent.emit();
|
||||||
|
view.acknowledgeInvalidEvent.emit();
|
||||||
assertFalse(14 == testRoundState.players.get(i).hand.getSize());
|
assertFalse(14 == testRoundState.players.get(i).hand.getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue