Improved AI
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@514 72836036-5685-4462-b002-a69064685172
This commit is contained in:
parent
2d08646187
commit
a33b0a22ac
2 changed files with 219 additions and 57 deletions
|
@ -6,6 +6,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import jrummikub.model.GameSettings;
|
import jrummikub.model.GameSettings;
|
||||||
|
@ -64,14 +65,19 @@ public class TurnLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateStones() throws Contradiction {
|
public void updateStones() throws Contradiction {
|
||||||
checkJokers();
|
checkJokerCount();
|
||||||
for (int i : changedStones) {
|
for (int i : changedStones) {
|
||||||
stones.get(i).checkState();
|
stones.get(i).checkState();
|
||||||
}
|
}
|
||||||
checkScoreAndPoints();
|
checkScoreAndPoints();
|
||||||
while (!changedStones.isEmpty()) {
|
while (!changedStones.isEmpty()) {
|
||||||
updateStonesStep();
|
while (!changedStones.isEmpty()) {
|
||||||
|
updateStonesStep();
|
||||||
|
checkScoreAndPoints();
|
||||||
|
}
|
||||||
|
checkJokerCount();
|
||||||
checkScoreAndPoints();
|
checkScoreAndPoints();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,33 +103,20 @@ public class TurnLogic {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkJokers() throws Contradiction {
|
private void checkJokerCount() throws Contradiction {
|
||||||
for (int i = 0; i < jokerIDs.size(); i++) {
|
int jokersLeft = jokerIDs.size();
|
||||||
StoneState left = stones.get(jokerIDs.get(i));
|
int jokersRight = jokerIDs.size();
|
||||||
|
for (StoneState stone : stones) {
|
||||||
HashSet<Integer> leftLeftGroup = new HashSet<Integer>(left.leftGroup);
|
if (stone.needsJoker(true)) {
|
||||||
HashSet<Integer> leftLeftRun = new HashSet<Integer>(left.leftRun);
|
jokersLeft--;
|
||||||
leftLeftGroup.remove(null);
|
if (jokersLeft < 0) {
|
||||||
leftLeftRun.remove(null);
|
throw new Contradiction();
|
||||||
int runID, groupID;
|
|
||||||
if (leftLeftGroup.isEmpty()) {
|
|
||||||
groupID = -1;
|
|
||||||
} else {
|
|
||||||
groupID = Collections.min(leftLeftGroup);
|
|
||||||
}
|
|
||||||
if (leftLeftRun.isEmpty()) {
|
|
||||||
runID = -1;
|
|
||||||
} else {
|
|
||||||
runID = Collections.min(leftLeftRun);
|
|
||||||
}
|
|
||||||
for (int j = i + 1; j < jokerIDs.size(); j++) {
|
|
||||||
StoneState right = stones.get(jokerIDs.get(j));
|
|
||||||
|
|
||||||
if (right.leftGroup.remove(groupID)) {
|
|
||||||
changedStones.add(jokerIDs.get(j));
|
|
||||||
}
|
}
|
||||||
if (right.leftRun.remove(runID)) {
|
}
|
||||||
changedStones.add(jokerIDs.get(j));
|
if (stone.needsJoker(false)) {
|
||||||
|
jokersRight--;
|
||||||
|
if (jokersRight < 0) {
|
||||||
|
throw new Contradiction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,8 +207,8 @@ public class TurnLogic {
|
||||||
public boolean isInterested(HashSet<Integer> changes) {
|
public boolean isInterested(HashSet<Integer> changes) {
|
||||||
return !(Collections.disjoint(changes, leftRun)
|
return !(Collections.disjoint(changes, leftRun)
|
||||||
&& Collections.disjoint(changes, rightRun)
|
&& Collections.disjoint(changes, rightRun)
|
||||||
&& Collections.disjoint(changes, leftGroup) && Collections.disjoint(
|
&& Collections.disjoint(changes, leftGroup) && Collections
|
||||||
changes, rightGroup));
|
.disjoint(changes, rightGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Comparable<T>> boolean lessThan(T a, T b) {
|
public <T extends Comparable<T>> boolean lessThan(T a, T b) {
|
||||||
|
@ -265,14 +258,85 @@ 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 |= updateRightRuns(changes);
|
changed |= updateRightRuns(changes);
|
||||||
changed |= updateLeftRuns(changes);
|
changed |= updateLeftRuns(changes);
|
||||||
changed |= updateRightGroups(changes);
|
changed |= updateRightGroups(changes);
|
||||||
changed |= updateLeftGroups(changes);
|
changed |= updateLeftGroups(changes);
|
||||||
changed |= checkState();
|
changed |= checkState();
|
||||||
|
|
||||||
|
breakSymmetries(changes);
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean nonNullEquals(Object a, Object b) {
|
||||||
|
return a != null && b != null && a.equals(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void breakSymmetries(HashSet<Integer> changes)
|
||||||
|
throws Contradiction {
|
||||||
|
Integer mySym = symmetryBreakerValue();
|
||||||
|
if (mySym == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int other : changes) {
|
||||||
|
if (other == id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
StoneState otherStone = top.stones.get(other);
|
||||||
|
if (!(joker && otherStone.joker || nonNullEquals(value,
|
||||||
|
otherStone.value)
|
||||||
|
&& nonNullEquals(color, otherStone.color))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Integer otherSym = top.stones.get(other).symmetryBreakerValue();
|
||||||
|
if (otherSym == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mySym != -1 | otherSym != -1)
|
||||||
|
& ((id > other) != (mySym < otherSym))) {
|
||||||
|
throw new Contradiction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer symmetryBreakerValue() {
|
||||||
|
if (onTable != Boolean.TRUE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (leftRun.size() > 1 || leftGroup.size() > 1
|
||||||
|
|| rightRun.size() > 1 || rightGroup.size() > 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int mode;
|
||||||
|
int neighbor;
|
||||||
|
if (leftRun.contains(null)) {
|
||||||
|
if (leftGroup.contains(null)) {
|
||||||
|
if (rightRun.contains(null)) {
|
||||||
|
if (rightGroup.contains(null)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
mode = 0;
|
||||||
|
neighbor = rightGroup.iterator().next();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode = 1;
|
||||||
|
neighbor = rightRun.iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mode = 2;
|
||||||
|
neighbor = leftGroup.iterator().next();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode = 3;
|
||||||
|
neighbor = leftRun.iterator().next();
|
||||||
|
}
|
||||||
|
return neighbor + stoneCount * mode;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean updateRightRuns(HashSet<Integer> changes)
|
public boolean updateRightRuns(HashSet<Integer> changes)
|
||||||
throws Contradiction {
|
throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
|
@ -283,7 +347,8 @@ public class TurnLogic {
|
||||||
if (!other.runNeighbor(this) || !other.rightRun.contains(id)) {
|
if (!other.runNeighbor(this) || !other.rightRun.contains(id)) {
|
||||||
leftRun.remove(i);
|
leftRun.remove(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (other.rightRun.size() == 1 && other.onTable == Boolean.TRUE) {
|
} else if (other.rightRun.size() == 1
|
||||||
|
&& other.onTable == Boolean.TRUE) {
|
||||||
changed |= leftRun.retainAll(Arrays.asList(i));
|
changed |= leftRun.retainAll(Arrays.asList(i));
|
||||||
changed |= onTable != Boolean.TRUE;
|
changed |= onTable != Boolean.TRUE;
|
||||||
onTable = true;
|
onTable = true;
|
||||||
|
@ -303,7 +368,8 @@ public class TurnLogic {
|
||||||
if (!this.runNeighbor(other) || !other.leftRun.contains(id)) {
|
if (!this.runNeighbor(other) || !other.leftRun.contains(id)) {
|
||||||
rightRun.remove(i);
|
rightRun.remove(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (other.leftRun.size() == 1 && other.onTable == Boolean.TRUE) {
|
} else if (other.leftRun.size() == 1
|
||||||
|
&& other.onTable == Boolean.TRUE) {
|
||||||
changed |= rightRun.retainAll(Arrays.asList(i));
|
changed |= rightRun.retainAll(Arrays.asList(i));
|
||||||
changed |= onTable != Boolean.TRUE;
|
changed |= onTable != Boolean.TRUE;
|
||||||
onTable = true;
|
onTable = true;
|
||||||
|
@ -320,7 +386,8 @@ public class TurnLogic {
|
||||||
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);
|
||||||
if (!other.groupNeighbor(this) || !other.rightGroup.contains(id)) {
|
if (!other.groupNeighbor(this)
|
||||||
|
|| !other.rightGroup.contains(id)) {
|
||||||
leftGroup.remove(i);
|
leftGroup.remove(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (other.rightGroup.size() == 1
|
} else if (other.rightGroup.size() == 1
|
||||||
|
@ -345,7 +412,8 @@ public class TurnLogic {
|
||||||
if (!this.groupNeighbor(other) || !other.leftGroup.contains(id)) {
|
if (!this.groupNeighbor(other) || !other.leftGroup.contains(id)) {
|
||||||
rightGroup.remove(i);
|
rightGroup.remove(i);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (other.leftGroup.size() == 1 && other.onTable == Boolean.TRUE) {
|
} else if (other.leftGroup.size() == 1
|
||||||
|
&& other.onTable == Boolean.TRUE) {
|
||||||
changed |= rightGroup.retainAll(Arrays.asList(i));
|
changed |= rightGroup.retainAll(Arrays.asList(i));
|
||||||
changed |= onTable != Boolean.TRUE;
|
changed |= onTable != Boolean.TRUE;
|
||||||
onTable = true;
|
onTable = true;
|
||||||
|
@ -401,8 +469,9 @@ public class TurnLogic {
|
||||||
private boolean checkLonelyStone() {
|
private boolean checkLonelyStone() {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(leftGroup,
|
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(
|
||||||
rightGroup, leftRun, rightRun, leftGroup, rightGroup, leftRun);
|
leftGroup, rightGroup, leftRun, rightRun, leftGroup,
|
||||||
|
rightGroup, leftRun);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (isNullSet(sets.get(i)) && isNullSet(sets.get(i + 1))
|
if (isNullSet(sets.get(i)) && isNullSet(sets.get(i + 1))
|
||||||
&& isNullSet(sets.get(i + 2))) {
|
&& isNullSet(sets.get(i + 2))) {
|
||||||
|
@ -436,8 +505,8 @@ public class TurnLogic {
|
||||||
|
|
||||||
private boolean checkStoneCanBeOnTable() throws Contradiction {
|
private boolean checkStoneCanBeOnTable() throws Contradiction {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (leftGroup.isEmpty() || rightGroup.isEmpty() || leftRun.isEmpty()
|
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|
||||||
|| rightRun.isEmpty()) {
|
|| leftRun.isEmpty() || rightRun.isEmpty()) {
|
||||||
if (onTable == Boolean.TRUE) {
|
if (onTable == Boolean.TRUE) {
|
||||||
throw new Contradiction();
|
throw new Contradiction();
|
||||||
}
|
}
|
||||||
|
@ -461,7 +530,36 @@ public class TurnLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkJoker() {
|
private boolean checkJoker() {
|
||||||
return false;
|
boolean changed = false;
|
||||||
|
if (this.value == null) {
|
||||||
|
if (isSingleNonNullSet(leftGroup)) {
|
||||||
|
this.value = top.stones.get(leftGroup.iterator().next()).value;
|
||||||
|
} else if (isSingleNonNullSet(rightGroup)) {
|
||||||
|
this.value = top.stones.get(rightGroup.iterator().next()).value;
|
||||||
|
} else if (isSingleNonNullSet(leftRun)) {
|
||||||
|
Integer value = top.stones.get(leftRun.iterator().next()).value;
|
||||||
|
if (value != null) {
|
||||||
|
this.value = value % settings.getHighestValue() + 1;
|
||||||
|
}
|
||||||
|
} else if (isSingleNonNullSet(rightRun)) {
|
||||||
|
Integer value = top.stones.get(rightRun.iterator().next()).value;
|
||||||
|
if (value != null) {
|
||||||
|
this.value = (value - 2) % settings.getHighestValue()
|
||||||
|
+ 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changed |= this.value != null;
|
||||||
|
}
|
||||||
|
if (this.color == null) {
|
||||||
|
if (isSingleNonNullSet(leftRun)) {
|
||||||
|
this.color = top.stones.get(leftRun.iterator().next()).color;
|
||||||
|
} else if (isSingleNonNullSet(rightRun)) {
|
||||||
|
this.color = top.stones.get(rightRun.iterator().next()).color;
|
||||||
|
}
|
||||||
|
changed |= this.color != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSolved() {
|
public boolean isSolved() {
|
||||||
|
@ -471,8 +569,8 @@ public class TurnLogic {
|
||||||
if (onTable == null || color == null || value == null) {
|
if (onTable == null || color == null || value == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (leftRun.size() > 1 || rightRun.size() > 1 || leftGroup.size() > 1
|
if (leftRun.size() > 1 || rightRun.size() > 1
|
||||||
|| rightGroup.size() > 1) {
|
|| leftGroup.size() > 1 || rightGroup.size() > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -494,6 +592,32 @@ public class TurnLogic {
|
||||||
else
|
else
|
||||||
return (double) value;
|
return (double) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return leftGroup.size() + rightGroup.size() + leftRun.size()
|
||||||
|
+ rightRun.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public boolean needsJoker(boolean side) {
|
||||||
|
if (onTable != Boolean.TRUE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (HashSet<Integer> set : side ? Arrays
|
||||||
|
.asList(leftGroup, leftRun) : Arrays.asList(rightGroup,
|
||||||
|
rightRun)) {
|
||||||
|
cancle: if (!set.contains(null)) {
|
||||||
|
for (int idx : set) {
|
||||||
|
if (!top.stones.get(idx).joker) {
|
||||||
|
break cancle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNullSet(HashSet<Integer> i) {
|
private static boolean isNullSet(HashSet<Integer> i) {
|
||||||
|
@ -508,11 +632,11 @@ public class TurnLogic {
|
||||||
* Creates new turn logic
|
* Creates new turn logic
|
||||||
*
|
*
|
||||||
* @param settings
|
* @param settings
|
||||||
* the game settings
|
* the game settings
|
||||||
* @param tableStones
|
* @param tableStones
|
||||||
* all stones on the table
|
* all stones on the table
|
||||||
* @param handStones
|
* @param handStones
|
||||||
* all stones on the hand
|
* 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) {
|
||||||
|
@ -541,26 +665,33 @@ public class TurnLogic {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Pair<Stone, Boolean> o1, Pair<Stone, Boolean> o2) {
|
public int compare(Pair<Stone, Boolean> o1, Pair<Stone, Boolean> o2) {
|
||||||
int cmp;
|
int cmp;
|
||||||
cmp = ((Boolean) o1.getFirst().isJoker()).compareTo(o2.getFirst()
|
cmp = ((Boolean) o1.getFirst().isJoker()).compareTo(o2
|
||||||
.isJoker());
|
.getFirst().isJoker());
|
||||||
if (cmp != 0) {
|
if (cmp != 0) {
|
||||||
return -cmp;
|
return -cmp;
|
||||||
}
|
}
|
||||||
cmp = (o1.getFirst().getColor()).compareTo(o2.getFirst().getColor());
|
cmp = (o1.getFirst().getColor()).compareTo(o2.getFirst()
|
||||||
|
.getColor());
|
||||||
if (cmp != 0) {
|
if (cmp != 0) {
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
cmp = ((Integer) o1.getFirst().getValue()).compareTo(o2.getFirst()
|
cmp = ((Integer) o1.getFirst().getValue()).compareTo(o2
|
||||||
.getValue());
|
.getFirst().getValue());
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
System.out.println("---");
|
||||||
|
ArrayList<Stone> handStones2 = new ArrayList<Stone>();
|
||||||
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());
|
inputStones.add(pair.getFirst());
|
||||||
|
if (!pair.getSecond()) {
|
||||||
|
handStones2.add(pair.getFirst());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
System.out.println(handStones2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -618,7 +749,8 @@ public class TurnLogic {
|
||||||
ArrayList<Stone> setStones = new ArrayList<Stone>();
|
ArrayList<Stone> setStones = new ArrayList<Stone>();
|
||||||
while (true) {
|
while (true) {
|
||||||
setStones.add(inputStones.get(stone.id));
|
setStones.add(inputStones.get(stone.id));
|
||||||
if (isNullSet(stone.rightRun) && isNullSet(stone.rightGroup)) {
|
if (isNullSet(stone.rightRun)
|
||||||
|
&& isNullSet(stone.rightGroup)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Integer rightRunID = stone.rightRun.iterator().next();
|
Integer rightRunID = stone.rightRun.iterator().next();
|
||||||
|
@ -669,18 +801,28 @@ public class TurnLogic {
|
||||||
public double optimize() {
|
public double optimize() {
|
||||||
while (!autoAbort && solve()) {
|
while (!autoAbort && solve()) {
|
||||||
neededScore = top.getScore();
|
neededScore = top.getScore();
|
||||||
|
System.out.println(neededScore);
|
||||||
}
|
}
|
||||||
return neededScore;
|
return neededScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void branch() throws Contradiction {
|
private void branch() throws Contradiction {
|
||||||
|
|
||||||
|
ArrayList<Integer> indices = new ArrayList<Integer>();
|
||||||
|
for (int i = 0; i < stoneCount; i++) {
|
||||||
|
indices.add(i);
|
||||||
|
}
|
||||||
|
Collections.sort(indices, new Comparator<Integer>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Integer o1, Integer o2) {
|
||||||
|
Integer size1 = top.stones.get(o1).getSize();
|
||||||
|
Integer size2 = top.stones.get(o2).getSize();
|
||||||
|
return size1.compareTo(size2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (int i = 0; i < stoneCount; i++) {
|
for (int i = 0; i < stoneCount; i++) {
|
||||||
StoneState stone = top.stones.get(i);
|
StoneState stone = top.stones.get(i);
|
||||||
if (stone.onTable == null) {
|
|
||||||
replace();
|
|
||||||
branchOnHand(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (stone.leftRun.size() > 1) {
|
if (stone.leftRun.size() > 1) {
|
||||||
replace();
|
replace();
|
||||||
branchLeftRun(i, stone);
|
branchLeftRun(i, stone);
|
||||||
|
@ -701,6 +843,14 @@ public class TurnLogic {
|
||||||
branchRightGroup(i, stone);
|
branchRightGroup(i, stone);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (stone.onTable == null) {
|
||||||
|
replace();
|
||||||
|
branchOnHand(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < stoneCount; i++) {
|
||||||
|
StoneState stone = top.stones.get(i);
|
||||||
if (stone.color == null) {
|
if (stone.color == null) {
|
||||||
replace();
|
replace();
|
||||||
branchColor(i);
|
branchColor(i);
|
||||||
|
@ -776,10 +926,10 @@ public class TurnLogic {
|
||||||
|
|
||||||
private void branchOnHand(int i) {
|
private void branchOnHand(int i) {
|
||||||
State newState = new State(top);
|
State newState = new State(top);
|
||||||
newState.stones.get(i).onTable = false;
|
newState.stones.get(i).onTable = true;
|
||||||
newState.changedStones.add(i);
|
newState.changedStones.add(i);
|
||||||
State altState = new State(top);
|
State altState = new State(top);
|
||||||
altState.stones.get(i).onTable = true;
|
altState.stones.get(i).onTable = false;
|
||||||
altState.changedStones.add(i);
|
altState.changedStones.add(i);
|
||||||
pushes(altState, newState);
|
pushes(altState, newState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,6 +232,18 @@ public class HandTest {
|
||||||
stones.add(new Stone(i, BLACK));
|
stones.add(new Stone(i, BLACK));
|
||||||
}
|
}
|
||||||
testInitialMeld(true, stones);
|
testInitialMeld(true, stones);
|
||||||
|
|
||||||
|
testInitialMeld(true, Arrays.asList(new Stone(1, BLACK), new Stone(1,
|
||||||
|
BLACK), new Stone(2, BLACK), new Stone(8, BLACK), new Stone(9,
|
||||||
|
BLACK), new Stone(10, BLACK), new Stone(11, BLACK), new Stone(
|
||||||
|
12, BLACK), new Stone(12, BLACK), new Stone(3, ORANGE),
|
||||||
|
new Stone(3, ORANGE), new Stone(5, ORANGE),
|
||||||
|
new Stone(7, ORANGE), new Stone(12, ORANGE), new Stone(13,
|
||||||
|
ORANGE), new Stone(13, ORANGE), new Stone(2, BLUE),
|
||||||
|
new Stone(2, BLUE), new Stone(3, BLUE), new Stone(3, BLUE),
|
||||||
|
new Stone(8, BLUE), new Stone(9, BLUE), new Stone(1, RED),
|
||||||
|
new Stone(3, RED), new Stone(4, RED), new Stone(4, RED),
|
||||||
|
new Stone(5, RED), new Stone(8, RED)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
|
|
Reference in a new issue