package search.maze;
/**
* 2D Maze Search
*
* <p/>
* Copyright 1998-2012 by Mark Watson. All rights reserved.
* <p/>
* This software is can be used under either of the following licenses:
* <p/>
* 1. LGPL v3<br/>
* 2. Apache 2
* <p/>
*/
public class BreadthFirstSearchEngine extends AbstractSearchEngine {
public BreadthFirstSearchEngine(int width, int height) {
super(width, height);
doSearchOn2DGrid();
}
private void doSearchOn2DGrid() {
int width = maze.getWidth();
int height = maze.getHeight();
boolean alReadyVisitedFlag[][] = new boolean[width][height];
//float distanceToNode[][] = new float[width][height];
Location predecessor[][] = new Location[width][height];
LocationQueue queue = new LocationQueue();
for (int i=0; i<width; i++) {
for (int j=0; j<height; j++) {
alReadyVisitedFlag[i][j] = false;
//distanceToNode[i][j] = 10000000.0f;
predecessor[i][j] = null;
}
}
alReadyVisitedFlag[startLoc.x][startLoc.y] = true;
//distanceToNode[startLoc.width][startLoc.height] = 0.0f;
queue.addToBackOfQueue(startLoc);
boolean success = false;
outer:
while (queue.isEmpty() == false) {
Location head = queue.peekAtFrontOfQueue();
if (head == null) break; // ??
Location [] connected = getPossibleMoves(head);
for (int i=0; i<4; i++) {
if (connected[i] == null) break;
int w = connected[i].x;
int h = connected[i].y;
if (alReadyVisitedFlag[w][h] == false) {
//distanceToNode[w][h] = distanceToNode[w][h] + 1.0f;
alReadyVisitedFlag[w][h] = true;
predecessor[w][h] = head;
queue.addToBackOfQueue(connected[i]);
if (equals(connected[i], goalLoc)) {
success = true;
break outer; // we are done
}
}
}
queue.removeFromFrontOfQueue(); // ignore return value
}
// now calculate the shortest path from the predecessor array:
maxDepth = 0;
if (success) {
searchPath[maxDepth++] = goalLoc;
for (int i=0; i<100; i++) {
searchPath[maxDepth] = predecessor[searchPath[maxDepth - 1].x][searchPath[maxDepth - 1].y];
maxDepth++;
if (equals(searchPath[maxDepth - 1], startLoc)) break; // back to starting node
}
}
}
protected class LocationQueue {
public LocationQueue(int num) {
queue = new Location[num];
head = tail = 0;
len = num;
}
public LocationQueue() {
this(400);
}
public void addToBackOfQueue(Location n) {
queue[tail] = n;
if (tail >= (len - 1)) {
tail = 0;
} else {
tail++;
}
}
public Location removeFromFrontOfQueue() {
Location ret = queue[head];
if (head >= (len - 1)) {
head = 0;
} else {
head++;
}
return ret;
}
public boolean isEmpty() {
return head == (tail + 1);
}
public Location peekAtFrontOfQueue() {
return queue[head];
}
private Location [] queue;
private int tail, head, len;
}
}