Added several comments in TurnLogic
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@532 72836036-5685-4462-b002-a69064685172
This commit is contained in:
parent
bafbd6cac1
commit
900554a09b
1 changed files with 130 additions and 39 deletions
|
@ -36,19 +36,43 @@ public class TurnLogic {
|
|||
private int neededPoints = 0;
|
||||
private double neededScore = 0;
|
||||
|
||||
/**
|
||||
* A Contradiction is thrown once a state is reached that isn't legal
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class Contradiction extends Throwable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The state the search is in, containing {@link StoneState}s
|
||||
*/
|
||||
private class State {
|
||||
/**
|
||||
* A list of all stones
|
||||
*/
|
||||
ArrayList<StoneState> stones = new ArrayList<StoneState>();
|
||||
/**
|
||||
* The stones that were changed since the previous state
|
||||
*/
|
||||
HashSet<Integer> changedStones = new HashSet<Integer>();
|
||||
/**
|
||||
* The position of the jokers in the other lists
|
||||
*/
|
||||
ArrayList<Integer> jokerIDs = new ArrayList<Integer>();
|
||||
|
||||
/**
|
||||
* Create a new
|
||||
*/
|
||||
public State() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of a state
|
||||
*
|
||||
* @param state
|
||||
* the state to copy
|
||||
*/
|
||||
public State(State state) {
|
||||
for (StoneState stone : state.stones) {
|
||||
stones.add(new StoneState(stone));
|
||||
|
@ -56,6 +80,12 @@ public class TurnLogic {
|
|||
jokerIDs = state.jokerIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds stones to be considered in the state
|
||||
*
|
||||
* @param stone
|
||||
* the stone to add
|
||||
*/
|
||||
public void add(StoneState stone) {
|
||||
stones.add(stone);
|
||||
changedStones.add(stones.size() - 1);
|
||||
|
@ -64,6 +94,12 @@ public class TurnLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the stones to consider the changes of the changed stones
|
||||
*
|
||||
* @throws Contradiction
|
||||
* Is thrown if the changes contradict each other
|
||||
*/
|
||||
public void updateStones() throws Contradiction {
|
||||
checkJokerCount();
|
||||
for (int i : changedStones) {
|
||||
|
@ -81,6 +117,12 @@ public class TurnLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* One step in the update process
|
||||
*
|
||||
* @throws Contradiction
|
||||
* Is thrown if changes contradict each other
|
||||
*/
|
||||
public void updateStonesStep() throws Contradiction {
|
||||
HashSet<Integer> newChangedStones = new HashSet<Integer>();
|
||||
for (int i = 0; i < stoneCount; i++) {
|
||||
|
@ -94,6 +136,12 @@ public class TurnLogic {
|
|||
changedStones = newChangedStones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the stones have a definite value and the state is thereby
|
||||
* solved
|
||||
*
|
||||
* @return whether the state is solved
|
||||
*/
|
||||
public boolean isSolved() {
|
||||
for (StoneState stone : stones) {
|
||||
if (!stone.isSolved()) {
|
||||
|
@ -103,6 +151,12 @@ public class TurnLogic {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that not too many jokers are trying to be used
|
||||
*
|
||||
* @throws Contradiction
|
||||
* Is thrown if too many jokers are trying to be used
|
||||
*/
|
||||
private void checkJokerCount() throws Contradiction {
|
||||
int jokersLeft = jokerIDs.size();
|
||||
int jokersRight = jokerIDs.size();
|
||||
|
@ -122,6 +176,12 @@ public class TurnLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that enough points and a high enough score are reached
|
||||
*
|
||||
* @throws Contradiction
|
||||
* Is thrown if points are too few or score is too low
|
||||
*/
|
||||
public void checkScoreAndPoints() throws Contradiction {
|
||||
if (getPoints() < neededPoints) {
|
||||
throw new Contradiction();
|
||||
|
@ -131,6 +191,11 @@ public class TurnLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the points
|
||||
*
|
||||
* @return the amount of points
|
||||
*/
|
||||
public int getPoints() {
|
||||
int sum = 0;
|
||||
for (StoneState stone : stones) {
|
||||
|
@ -141,6 +206,11 @@ public class TurnLogic {
|
|||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the score
|
||||
*
|
||||
* @return the total score reached
|
||||
*/
|
||||
public double getScore() {
|
||||
double sum = 0;
|
||||
for (StoneState stone : stones) {
|
||||
|
@ -153,6 +223,10 @@ public class TurnLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the remaining possible values, colors, positions, etc. a stone can
|
||||
* take and its possible neighbors in a group or run
|
||||
*/
|
||||
private class StoneState {
|
||||
int id;
|
||||
boolean joker;
|
||||
|
@ -165,6 +239,16 @@ public class TurnLogic {
|
|||
HashSet<Integer> leftGroup;
|
||||
HashSet<Integer> rightGroup;
|
||||
|
||||
/**
|
||||
* Creates a new
|
||||
*
|
||||
* @param id
|
||||
* the stone's identifier
|
||||
* @param stone
|
||||
* the stone
|
||||
* @param table
|
||||
* whether is on the table
|
||||
*/
|
||||
public StoneState(int id, Stone stone, boolean table) {
|
||||
this.id = id;
|
||||
joker = stone.isJoker();
|
||||
|
@ -180,6 +264,12 @@ public class TurnLogic {
|
|||
rightGroup = makeFullSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy
|
||||
*
|
||||
* @param stone
|
||||
* the state to copy
|
||||
*/
|
||||
public StoneState(StoneState stone) {
|
||||
this.id = stone.id;
|
||||
this.joker = stone.joker;
|
||||
|
@ -193,6 +283,11 @@ public class TurnLogic {
|
|||
this.rightGroup = new HashSet<Integer>(stone.rightGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set containing all possible neighbors
|
||||
*
|
||||
* @return the set
|
||||
*/
|
||||
private HashSet<Integer> makeFullSet() {
|
||||
HashSet<Integer> set = new HashSet<Integer>();
|
||||
for (int i = 0; i < stoneCount; i++) {
|
||||
|
@ -204,11 +299,18 @@ public class TurnLogic {
|
|||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the recent changes affect the stone
|
||||
*
|
||||
* @param changes
|
||||
* the changes
|
||||
* @return whether the stone is affected
|
||||
*/
|
||||
public boolean isInterested(HashSet<Integer> changes) {
|
||||
return !(Collections.disjoint(changes, leftRun)
|
||||
&& Collections.disjoint(changes, rightRun)
|
||||
&& Collections.disjoint(changes, leftGroup) && Collections
|
||||
.disjoint(changes, rightGroup));
|
||||
&& Collections.disjoint(changes, leftGroup) && Collections.disjoint(
|
||||
changes, rightGroup));
|
||||
}
|
||||
|
||||
public <T extends Comparable<T>> boolean lessThan(T a, T b) {
|
||||
|
@ -274,8 +376,7 @@ public class TurnLogic {
|
|||
return a != null && b != null && a.equals(b);
|
||||
}
|
||||
|
||||
private void breakSymmetries(HashSet<Integer> changes)
|
||||
throws Contradiction {
|
||||
private void breakSymmetries(HashSet<Integer> changes) throws Contradiction {
|
||||
Integer mySym = symmetryBreakerValue();
|
||||
if (mySym == null) {
|
||||
return;
|
||||
|
@ -286,8 +387,7 @@ public class TurnLogic {
|
|||
}
|
||||
StoneState otherStone = top.stones.get(other);
|
||||
if (!(joker && otherStone.joker || nonNullEquals(value,
|
||||
otherStone.value)
|
||||
&& nonNullEquals(color, otherStone.color))) {
|
||||
otherStone.value) && nonNullEquals(color, otherStone.color))) {
|
||||
continue;
|
||||
}
|
||||
Integer otherSym = top.stones.get(other).symmetryBreakerValue();
|
||||
|
@ -306,8 +406,8 @@ public class TurnLogic {
|
|||
if (onTable != Boolean.TRUE) {
|
||||
return -1;
|
||||
}
|
||||
if (leftRun.size() > 1 || leftGroup.size() > 1
|
||||
|| rightRun.size() > 1 || rightGroup.size() > 1) {
|
||||
if (leftRun.size() > 1 || leftGroup.size() > 1 || rightRun.size() > 1
|
||||
|| rightGroup.size() > 1) {
|
||||
return null;
|
||||
}
|
||||
int mode;
|
||||
|
@ -347,8 +447,7 @@ public class TurnLogic {
|
|||
if (!other.runNeighbor(this) || !other.rightRun.contains(id)) {
|
||||
leftRun.remove(i);
|
||||
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 |= onTable != Boolean.TRUE;
|
||||
onTable = true;
|
||||
|
@ -368,8 +467,7 @@ public class TurnLogic {
|
|||
if (!this.runNeighbor(other) || !other.leftRun.contains(id)) {
|
||||
rightRun.remove(i);
|
||||
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 |= onTable != Boolean.TRUE;
|
||||
onTable = true;
|
||||
|
@ -386,8 +484,7 @@ public class TurnLogic {
|
|||
relevantChanges.retainAll(changes);
|
||||
for (int i : relevantChanges) {
|
||||
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);
|
||||
changed = true;
|
||||
} else if (other.rightGroup.size() == 1
|
||||
|
@ -412,8 +509,7 @@ public class TurnLogic {
|
|||
if (!this.groupNeighbor(other) || !other.leftGroup.contains(id)) {
|
||||
rightGroup.remove(i);
|
||||
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 |= onTable != Boolean.TRUE;
|
||||
onTable = true;
|
||||
|
@ -470,9 +566,8 @@ public class TurnLogic {
|
|||
private boolean checkLonelyStone() {
|
||||
boolean changed = false;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(
|
||||
leftGroup, rightGroup, leftRun, rightRun, leftGroup,
|
||||
rightGroup, leftRun);
|
||||
List<HashSet<Integer>> sets = Arrays.<HashSet<Integer>> asList(leftGroup,
|
||||
rightGroup, leftRun, rightRun, leftGroup, rightGroup, leftRun);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (isNullSet(sets.get(i)) && isNullSet(sets.get(i + 1))
|
||||
&& isNullSet(sets.get(i + 2))) {
|
||||
|
@ -506,8 +601,8 @@ public class TurnLogic {
|
|||
|
||||
private boolean checkStoneCanBeOnTable() throws Contradiction {
|
||||
boolean changed = false;
|
||||
if (leftGroup.isEmpty() || rightGroup.isEmpty()
|
||||
|| leftRun.isEmpty() || rightRun.isEmpty()) {
|
||||
if (leftGroup.isEmpty() || rightGroup.isEmpty() || leftRun.isEmpty()
|
||||
|| rightRun.isEmpty()) {
|
||||
if (onTable == Boolean.TRUE) {
|
||||
throw new Contradiction();
|
||||
}
|
||||
|
@ -545,8 +640,7 @@ public class TurnLogic {
|
|||
} else if (isSingleNonNullSet(rightRun)) {
|
||||
Integer value = top.stones.get(rightRun.iterator().next()).value;
|
||||
if (value != null) {
|
||||
this.value = (value - 2) % settings.getHighestValue()
|
||||
+ 1;
|
||||
this.value = (value - 2) % settings.getHighestValue() + 1;
|
||||
}
|
||||
}
|
||||
changed |= this.value != null;
|
||||
|
@ -574,8 +668,8 @@ public class TurnLogic {
|
|||
if (onTable == null || color == null || value == null) {
|
||||
return false;
|
||||
}
|
||||
if (leftRun.size() > 1 || rightRun.size() > 1
|
||||
|| leftGroup.size() > 1 || rightGroup.size() > 1) {
|
||||
if (leftRun.size() > 1 || rightRun.size() > 1 || leftGroup.size() > 1
|
||||
|| rightGroup.size() > 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -603,9 +697,8 @@ public class TurnLogic {
|
|||
if (onTable != Boolean.TRUE) {
|
||||
return false;
|
||||
}
|
||||
for (HashSet<Integer> set : side ? Arrays
|
||||
.asList(leftGroup, leftRun) : Arrays.asList(rightGroup,
|
||||
rightRun)) {
|
||||
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) {
|
||||
|
@ -665,18 +758,17 @@ public class TurnLogic {
|
|||
@Override
|
||||
public int compare(Pair<Stone, Boolean> o1, Pair<Stone, Boolean> o2) {
|
||||
int cmp;
|
||||
cmp = ((Boolean) o1.getFirst().isJoker()).compareTo(o2
|
||||
.getFirst().isJoker());
|
||||
cmp = ((Boolean) o1.getFirst().isJoker()).compareTo(o2.getFirst()
|
||||
.isJoker());
|
||||
if (cmp != 0) {
|
||||
return -cmp;
|
||||
}
|
||||
cmp = (o1.getFirst().getColor()).compareTo(o2.getFirst()
|
||||
.getColor());
|
||||
cmp = (o1.getFirst().getColor()).compareTo(o2.getFirst().getColor());
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
cmp = ((Integer) o1.getFirst().getValue()).compareTo(o2
|
||||
.getFirst().getValue());
|
||||
cmp = ((Integer) o1.getFirst().getValue()).compareTo(o2.getFirst()
|
||||
.getValue());
|
||||
return cmp;
|
||||
}
|
||||
});
|
||||
|
@ -743,8 +835,7 @@ public class TurnLogic {
|
|||
ArrayList<Stone> setStones = new ArrayList<Stone>();
|
||||
while (true) {
|
||||
setStones.add(inputStones.get(stone.id));
|
||||
if (isNullSet(stone.rightRun)
|
||||
&& isNullSet(stone.rightGroup)) {
|
||||
if (isNullSet(stone.rightRun) && isNullSet(stone.rightGroup)) {
|
||||
break;
|
||||
}
|
||||
Integer rightRunID = stone.rightRun.iterator().next();
|
||||
|
|
Reference in a new issue