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:
Bennet Gerlach 2011-06-21 02:50:06 +02:00
parent bafbd6cac1
commit 900554a09b

View file

@ -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();