summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jrummikub/ai/TurnLogic.java130
-rw-r--r--src/jrummikub/model/Stone.java4
-rw-r--r--test/jrummikub/model/StoneSetTest.java4
3 files changed, 97 insertions, 41 deletions
diff --git a/src/jrummikub/ai/TurnLogic.java b/src/jrummikub/ai/TurnLogic.java
index 8318773..01a3d59 100644
--- a/src/jrummikub/ai/TurnLogic.java
+++ b/src/jrummikub/ai/TurnLogic.java
@@ -11,21 +11,26 @@ import java.util.List;
import jrummikub.model.GameSettings;
import jrummikub.model.Stone;
import jrummikub.model.StoneColor;
+import jrummikub.model.StoneSet;
import jrummikub.util.Pair;
public class TurnLogic {
- GameSettings settings;
- int stoneCount;
- StoneColor maxColor;
- StoneColor minColor;
- ArrayList<StoneColor> stoneColors;
-
- ArrayList<State> stack = new ArrayList<State>();
- State top;
-
- int neededPoints = 0;
- double neededScore = Double.NEGATIVE_INFINITY;
-
+ private GameSettings settings;
+ private int stoneCount;
+ private List<Stone> inputStones;
+ private StoneColor maxColor;
+ 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;
+
@SuppressWarnings("serial")
private static class Contradiction extends Throwable {
@@ -81,8 +86,9 @@ public class TurnLogic {
public boolean isSolved() {
for (StoneState stone : stones) {
- if (!stone.isSolved())
+ if (!stone.isSolved()) {
return false;
+ }
}
return true;
}
@@ -139,14 +145,14 @@ public class TurnLogic {
}
return sum;
}
-
+
public double getScore() {
double sum = 0;
for (StoneState stone : stones) {
if (stone.onTable != Boolean.FALSE) {
sum += stone.getScore();
}
-
+
}
return sum;
}
@@ -210,14 +216,6 @@ public class TurnLogic {
.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) {
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)
&& isNullSet(top.stones.get(leftRun.iterator().next()).leftRun)) {
changed |= rightRun.remove(null);
@@ -407,6 +394,26 @@ public class TurnLogic {
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();
return changed;
@@ -427,6 +434,9 @@ public class TurnLogic {
|| leftGroup.size() > 1 || rightGroup.size() > 1) {
return false;
}
+ if (!((isNullSet(leftRun) && isNullSet(rightRun)) || (isNullSet(leftGroup) && isNullSet(rightGroup)))) {
+ return false;
+ }
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,
Collection<Stone> handStones) {
this.settings = settings;
@@ -464,7 +482,7 @@ public class TurnLogic {
stack.add(top);
ArrayList<Pair<Stone, Boolean>> sortedStones = new ArrayList<Pair<Stone, Boolean>>();
-
+ inputStones = new ArrayList<Stone>();
for (Stone stone : tableStones) {
sortedStones.add(new Pair<Stone, Boolean>(stone, true));
}
@@ -494,9 +512,10 @@ public class TurnLogic {
int i = 0;
for (Pair<Stone, Boolean> pair : sortedStones) {
top.add(new StoneState(i++, pair.getFirst(), pair.getSecond()));
+ inputStones.add(pair.getFirst());
}
}
-
+
public void needIntialMeldThreshold() {
neededPoints = settings.getInitialMeldThreshold();
}
@@ -522,14 +541,53 @@ public class TurnLogic {
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() {
if (top.isSolved()) {
pop();
}
while (stack.size() != 0) {
+ if (abort) {
+ return false;
+ }
try {
top.updateStones();
if (top.isSolved()) {
+ bestState = top;
return true;
}
branch();
diff --git a/src/jrummikub/model/Stone.java b/src/jrummikub/model/Stone.java
index a6d62c4..5d61a56 100644
--- a/src/jrummikub/model/Stone.java
+++ b/src/jrummikub/model/Stone.java
@@ -77,9 +77,9 @@ public class Stone implements Sizeable, Serializable {
@Override
public String toString() {
if (joker) {
- return "Stone[joker,color=" + color + "]";
+ return "[" + color + " J]";
} else {
- return "Stone[value=" + value + ",color=" + color + "]";
+ return "[" + color + " " + value + "]";
}
}
}
diff --git a/test/jrummikub/model/StoneSetTest.java b/test/jrummikub/model/StoneSetTest.java
index aba38a5..d82f8f2 100644
--- a/test/jrummikub/model/StoneSetTest.java
+++ b/test/jrummikub/model/StoneSetTest.java
@@ -364,8 +364,6 @@ public class StoneSetTest {
StoneSet testSet = new StoneSet(Arrays.asList(new Stone(2, BLUE),
new Stone(3, BLUE), new Stone(4, BLUE)));
- assertEquals(
- "StoneSet[Stone[value=2,color=BLUE],Stone[value=3,color=BLUE],Stone[value=4,color=BLUE]]",
- testSet.toString());
+ assertEquals("StoneSet[[BLUE 2],[BLUE 3],[BLUE 4]]", testSet.toString());
}
}