package jrummikub.ai.fdsolver; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; public class Var implements Comparable> { private Solver solver; private HashSet range; private HashSet constraints; private T recorded; public Var(Solver solver, Collection range) { this.solver = solver; this.range = new HashSet(range); constraints = new HashSet(); } public T getValue() { if (range.size() != 1) return null; return range.iterator().next(); } public HashSet getRange() { return range; } void choose(T value) { for (Iterator i = this.iterator(); i.hasNext();) { if (i.next() != value) { i.remove(); } } } void makeDirty() { this.solver.dirtyVars.add(this); } public void invalidate(T value) { range.remove(value); solver.logInvalidation(this, value); makeDirty(); if (range.size() == 0) { solver.contradiction = true; } } HashSet getConstraints() { return constraints; } public Iterator iterator() { final Iterator iterator = range.iterator(); return new Iterator() { T lastValue; @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { lastValue = iterator.next(); return lastValue; } @Override public void remove() { // TODO logging iterator.remove(); solver.logInvalidation(Var.this, lastValue); makeDirty(); if (range.size() == 0) { solver.contradiction = true; } } }; } void record() { recorded = getValue(); } void restore() { range.clear(); range.add(recorded); } @Override public String toString() { return "Var" + range; } private int neighborCount() { /* int count = 0; for (Constraint constraint : constraints) { count += constraint.getWatchedVars().size(); } */ return constraints.size(); } @Override public int compareTo(Var other) { int rangeCompare = ((Integer)range.size()).compareTo(other.range.size()); if (rangeCompare != 0) return rangeCompare; return -((Integer)neighborCount()).compareTo(other.neighborCount()); } }