Implemented getResult and abort in TurnLogic

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@445 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Jannis Harder 2011-06-17 17:41:55 +02:00
parent 5ae0590dbc
commit 2c9f1d5d20
3 changed files with 96 additions and 40 deletions

View file

@ -11,21 +11,26 @@ import java.util.List;
import jrummikub.model.GameSettings; import jrummikub.model.GameSettings;
import jrummikub.model.Stone; import jrummikub.model.Stone;
import jrummikub.model.StoneColor; import jrummikub.model.StoneColor;
import jrummikub.model.StoneSet;
import jrummikub.util.Pair; import jrummikub.util.Pair;
public class TurnLogic { public class TurnLogic {
GameSettings settings; private GameSettings settings;
int stoneCount; private int stoneCount;
StoneColor maxColor; private List<Stone> inputStones;
StoneColor minColor; private StoneColor maxColor;
ArrayList<StoneColor> stoneColors; private StoneColor minColor;
private ArrayList<StoneColor> stoneColors;
private volatile State bestState;
private ArrayList<State> stack = new ArrayList<State>();
private State top;
private volatile boolean abort = false;
private int neededPoints = 0;
private double neededScore = Double.NEGATIVE_INFINITY;
ArrayList<State> stack = new ArrayList<State>();
State top;
int neededPoints = 0;
double neededScore = Double.NEGATIVE_INFINITY;
@SuppressWarnings("serial") @SuppressWarnings("serial")
private static class Contradiction extends Throwable { private static class Contradiction extends Throwable {
@ -81,8 +86,9 @@ public class TurnLogic {
public boolean isSolved() { public boolean isSolved() {
for (StoneState stone : stones) { for (StoneState stone : stones) {
if (!stone.isSolved()) if (!stone.isSolved()) {
return false; return false;
}
} }
return true; return true;
} }
@ -139,14 +145,14 @@ public class TurnLogic {
} }
return sum; return sum;
} }
public double getScore() { public double getScore() {
double sum = 0; double sum = 0;
for (StoneState stone : stones) { for (StoneState stone : stones) {
if (stone.onTable != Boolean.FALSE) { if (stone.onTable != Boolean.FALSE) {
sum += stone.getScore(); sum += stone.getScore();
} }
} }
return sum; return sum;
} }
@ -210,14 +216,6 @@ public class TurnLogic {
.disjoint(changes, rightGroup)); .disjoint(changes, rightGroup));
} }
private boolean isNullSet(HashSet<Integer> i) {
return i.size() == 1 && i.contains(null);
}
private boolean isSingleNonNullSet(HashSet<Integer> i) {
return i.size() == 1 && !i.contains(null);
}
public <T extends Comparable<T>> boolean lessThan(T a, T b) { public <T extends Comparable<T>> boolean lessThan(T a, T b) {
return a == null || b == null || a.compareTo(b) < 0; return a == null || b == null || a.compareTo(b) < 0;
} }
@ -378,17 +376,6 @@ public class TurnLogic {
} }
} }
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|| leftRun.isEmpty() || rightRun.isEmpty()) {
if (onTable == Boolean.TRUE) {
throw new Contradiction();
}
if (onTable == null) {
onTable = false;
changed = true;
}
}
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);
@ -407,6 +394,26 @@ public class TurnLogic {
changed |= leftGroup.remove(null); changed |= leftGroup.remove(null);
} }
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|| leftRun.isEmpty() || rightRun.isEmpty()) {
if (onTable == Boolean.TRUE) {
throw new Contradiction();
}
if (onTable == null) {
onTable = false;
leftRun.clear();
rightRun.clear();
leftGroup.clear();
rightGroup.clear();
changed = true;
}
}
if ((isSingleNonNullSet(leftGroup) || isSingleNonNullSet(rightGroup))
&& (isSingleNonNullSet(leftRun) || isSingleNonNullSet(rightRun))) {
throw new Contradiction();
}
changed |= checkJoker(); changed |= checkJoker();
return changed; return changed;
@ -427,6 +434,9 @@ public class TurnLogic {
|| leftGroup.size() > 1 || rightGroup.size() > 1) { || leftGroup.size() > 1 || rightGroup.size() > 1) {
return false; return false;
} }
if (!((isNullSet(leftRun) && isNullSet(rightRun)) || (isNullSet(leftGroup) && isNullSet(rightGroup)))) {
return false;
}
return true; return true;
} }
@ -448,6 +458,14 @@ public class TurnLogic {
} }
} }
private static boolean isNullSet(HashSet<Integer> i) {
return i.size() == 1 && i.contains(null);
}
private static boolean isSingleNonNullSet(HashSet<Integer> i) {
return i.size() == 1 && !i.contains(null);
}
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;
@ -464,7 +482,7 @@ public class TurnLogic {
stack.add(top); stack.add(top);
ArrayList<Pair<Stone, Boolean>> sortedStones = new ArrayList<Pair<Stone, Boolean>>(); ArrayList<Pair<Stone, Boolean>> sortedStones = new ArrayList<Pair<Stone, Boolean>>();
inputStones = new ArrayList<Stone>();
for (Stone stone : tableStones) { for (Stone stone : tableStones) {
sortedStones.add(new Pair<Stone, Boolean>(stone, true)); sortedStones.add(new Pair<Stone, Boolean>(stone, true));
} }
@ -494,9 +512,10 @@ public class TurnLogic {
int i = 0; int i = 0;
for (Pair<Stone, Boolean> pair : sortedStones) { for (Pair<Stone, Boolean> pair : sortedStones) {
top.add(new StoneState(i++, pair.getFirst(), pair.getSecond())); top.add(new StoneState(i++, pair.getFirst(), pair.getSecond()));
inputStones.add(pair.getFirst());
} }
} }
public void needIntialMeldThreshold() { public void needIntialMeldThreshold() {
neededPoints = settings.getInitialMeldThreshold(); neededPoints = settings.getInitialMeldThreshold();
} }
@ -522,14 +541,53 @@ public class TurnLogic {
top = stack.get(stack.size() - 1); top = stack.get(stack.size() - 1);
} }
public void abort() {
abort = true;
}
public List<StoneSet> getResult() {
State result = bestState;
ArrayList<StoneSet> outputSets = new ArrayList<StoneSet>();
for (int i = 0; i < stoneCount; i++) {
StoneState stone = result.stones.get(i);
if (isNullSet(stone.leftRun) && isNullSet(stone.leftGroup)) {
ArrayList<Stone> setStones = new ArrayList<Stone>();
while (true) {
setStones.add(inputStones.get(stone.id));
if (isNullSet(stone.rightRun)
&& isNullSet(stone.rightGroup)) {
break;
}
/* System.out.println("--");
System.out.println(stone.rightRun);
System.out.println(stone.rightGroup); */
Integer rightRunID = stone.rightRun.iterator().next();
Integer rightGroupID = stone.rightGroup.iterator().next();
stone = result.stones.get(rightRunID == null ? rightGroupID
: rightRunID);
}
outputSets.add(new StoneSet(setStones));
}
}
return outputSets;
}
public boolean solve() { public boolean solve() {
if (top.isSolved()) { if (top.isSolved()) {
pop(); pop();
} }
while (stack.size() != 0) { while (stack.size() != 0) {
if (abort) {
return false;
}
try { try {
top.updateStones(); top.updateStones();
if (top.isSolved()) { if (top.isSolved()) {
bestState = top;
return true; return true;
} }
branch(); branch();

View file

@ -77,9 +77,9 @@ public class Stone implements Sizeable, Serializable {
@Override @Override
public String toString() { public String toString() {
if (joker) { if (joker) {
return "Stone[joker,color=" + color + "]"; return "[" + color + " J]";
} else { } else {
return "Stone[value=" + value + ",color=" + color + "]"; return "[" + color + " " + value + "]";
} }
} }
} }

View file

@ -364,8 +364,6 @@ public class StoneSetTest {
StoneSet testSet = new StoneSet(Arrays.asList(new Stone(2, BLUE), StoneSet testSet = new StoneSet(Arrays.asList(new Stone(2, BLUE),
new Stone(3, BLUE), new Stone(4, BLUE))); new Stone(3, BLUE), new Stone(4, BLUE)));
assertEquals( assertEquals("StoneSet[[BLUE 2],[BLUE 3],[BLUE 4]]", testSet.toString());
"StoneSet[Stone[value=2,color=BLUE],Stone[value=3,color=BLUE],Stone[value=4,color=BLUE]]",
testSet.toString());
} }
} }