use of com.cburch.logisim.data.Location in project logisim-evolution by reds-heig.
the class Connector method findShortestPath.
private static SearchNode findShortestPath(List<SearchNode> nodes, Set<Location> pathLocs, AvoidanceMap avoid) {
PriorityQueue<SearchNode> q = new PriorityQueue<SearchNode>(nodes);
HashSet<SearchNode> visited = new HashSet<SearchNode>();
int iters = 0;
while (!q.isEmpty() && iters < MAX_SEARCH_ITERATIONS) {
iters++;
SearchNode n = q.remove();
if (iters % 64 == 0 && ConnectorThread.isOverrideRequested() || n == null) {
return null;
}
if (n.isDestination()) {
return n;
}
boolean added = visited.add(n);
if (!added) {
continue;
}
Location loc = n.getLocation();
Direction dir = n.getDirection();
int neighbors = 3;
Object allowed = avoid.get(loc);
if (allowed != null && n.isStart() && pathLocs.contains(loc)) {
allowed = null;
}
if (allowed == ALLOW_NEITHER) {
neighbors = 0;
} else if (allowed == ALLOW_VERTICAL) {
if (dir == null) {
dir = Direction.NORTH;
neighbors = 2;
} else if (dir == Direction.NORTH || dir == Direction.SOUTH) {
neighbors = 1;
} else {
neighbors = 0;
}
} else if (allowed == ALLOW_HORIZONTAL) {
if (dir == null) {
dir = Direction.EAST;
neighbors = 2;
} else if (dir == Direction.EAST || dir == Direction.WEST) {
neighbors = 1;
} else {
neighbors = 0;
}
} else {
if (dir == null) {
dir = Direction.NORTH;
neighbors = 4;
} else {
neighbors = 3;
}
}
for (int i = 0; i < neighbors; i++) {
Direction oDir;
switch(i) {
case 0:
oDir = dir;
break;
case 1:
oDir = neighbors == 2 ? dir.reverse() : dir.getLeft();
break;
case 2:
oDir = dir.getRight();
break;
default:
// must be 3
oDir = dir.reverse();
}
SearchNode o = n.next(oDir, allowed != null);
if (o != null && !visited.contains(o)) {
q.add(o);
}
}
}
return null;
}
use of com.cburch.logisim.data.Location in project logisim-evolution by reds-heig.
the class Connector method pruneImpossible.
private static ArrayList<ConnectionData> pruneImpossible(ArrayList<ConnectionData> connects, AvoidanceMap avoid, int dx, int dy) {
ArrayList<Wire> pathWires = new ArrayList<Wire>();
for (ConnectionData conn : connects) {
for (Wire w : conn.getWirePath()) {
pathWires.add(w);
}
}
ArrayList<ConnectionData> impossible = new ArrayList<ConnectionData>();
for (Iterator<ConnectionData> it = connects.iterator(); it.hasNext(); ) {
ConnectionData conn = it.next();
Location dest = conn.getLocation().translate(dx, dy);
if (avoid.get(dest) != null) {
boolean isInPath = false;
for (Wire w : pathWires) {
if (w.contains(dest)) {
isInPath = true;
break;
}
}
if (!isInPath) {
it.remove();
impossible.add(conn);
}
}
}
return impossible;
}
use of com.cburch.logisim.data.Location in project logisim-evolution by reds-heig.
the class Connector method processConnection.
private static void processConnection(ConnectionData conn, int dx, int dy, HashSet<Location> connLocs, ArrayList<SearchNode> connNodes, AvoidanceMap selAvoid) {
Location cur = conn.getLocation();
Location dest = cur.translate(dx, dy);
if (selAvoid.get(cur) == null) {
Direction preferred = conn.getDirection();
if (preferred == null) {
if (Math.abs(dx) > Math.abs(dy)) {
preferred = dx > 0 ? Direction.EAST : Direction.WEST;
} else {
preferred = dy > 0 ? Direction.SOUTH : Direction.NORTH;
}
}
connLocs.add(cur);
connNodes.add(new SearchNode(conn, cur, preferred, dest));
}
for (Wire w : conn.getWirePath()) {
for (Location loc : w) {
if (selAvoid.get(loc) == null || loc.equals(dest)) {
boolean added = connLocs.add(loc);
if (added) {
Direction dir = null;
if (w.endsAt(loc)) {
if (w.isVertical()) {
int y0 = loc.getY();
int y1 = w.getOtherEnd(loc).getY();
dir = y0 < y1 ? Direction.NORTH : Direction.SOUTH;
} else {
int x0 = loc.getX();
int x1 = w.getOtherEnd(loc).getX();
dir = x0 < x1 ? Direction.WEST : Direction.EAST;
}
}
connNodes.add(new SearchNode(conn, loc, dir, dest));
}
}
}
}
}
use of com.cburch.logisim.data.Location in project logisim-evolution by reds-heig.
the class SearchNode method next.
public SearchNode next(Direction moveDir, boolean crossing) {
int newDist = dist;
Direction connDir = conn.getDirection();
Location nextLoc = loc.translate(moveDir, 10);
boolean exWire = extendsWire && moveDir == connDir;
if (exWire) {
newDist += 9;
} else {
newDist += 10;
}
if (crossing)
newDist += CROSSING_PENALTY;
if (moveDir != dir)
newDist += TURN_PENALTY;
if (nextLoc.getX() < 0 || nextLoc.getY() < 0) {
return null;
} else {
return new SearchNode(nextLoc, moveDir, conn, dest, newDist, exWire, this);
}
}
use of com.cburch.logisim.data.Location in project logisim-evolution by reds-heig.
the class SearchNode method getHeuristic.
private int getHeuristic() {
Location cur = loc;
Location dst = dest;
Direction curDir = dir;
int dx = dst.getX() - cur.getX();
int dy = dst.getY() - cur.getY();
int ret = -1;
if (extendsWire) {
ret = -1;
if (curDir == Direction.EAST) {
if (dx > 0)
ret = dx / 10 * 9 + Math.abs(dy);
} else if (curDir == Direction.WEST) {
if (dx < 0)
ret = -dx / 10 * 9 + Math.abs(dy);
} else if (curDir == Direction.SOUTH) {
if (dy > 0)
ret = Math.abs(dx) + dy / 10 * 9;
} else if (curDir == Direction.NORTH) {
if (dy < 0)
ret = Math.abs(dx) - dy / 10 * 9;
}
}
if (ret < 0) {
ret = Math.abs(dx) + Math.abs(dy);
}
boolean penalizeDoubleTurn = false;
if (curDir == Direction.EAST) {
penalizeDoubleTurn = dx < 0;
} else if (curDir == Direction.WEST) {
penalizeDoubleTurn = dx > 0;
} else if (curDir == Direction.NORTH) {
penalizeDoubleTurn = dy > 0;
} else if (curDir == Direction.SOUTH) {
penalizeDoubleTurn = dy < 0;
} else if (curDir == null) {
if (dx != 0 || dy != 0)
ret += TURN_PENALTY;
}
if (penalizeDoubleTurn) {
ret += 2 * TURN_PENALTY;
} else if (dx != 0 && dy != 0) {
ret += TURN_PENALTY;
}
return ret;
}
Aggregations