My point is that you don’t need the Node[][] array - the map tells you where you can and can’t go
Here’s my (fairly generic) a* code;
NB for diagonal moves modify the ‘+1’ in getNeighbours() to ‘+sqrt(2)’ to add to the cost
public class PathNode
{
int x;
int y;
double cost;
double dist;
PathNode parent = null;
public PathNode(int xIn, int yIn, double costIn, double distIn) {
x = xIn;
y = yIn;
cost = costIn;
dist = distIn;
}
}
/******************************************************************
* getNeighbours
* function used in pathfinding
******************************************************************/
private Vector getNeighbours(int x, int y, double cost, int tx, int ty) {
Vector list = new Vector();
for (int dx=-1; dx<2; dx++)
{
for (int dy=-1; dy<2; dy++)
{
if ((dx != 0) || (dy != 0))
{
if ((x+dx>-1) && (x+dx<gridWidth) && (y+dy>-1) && (y+dy<gridHeight))
{
int content=readMap(x+dx,y+dy);
if (content==EMPTY) // if empty
{
double dist = range(x, y, tx, ty);
list.addElement(new PathNode(x + dx, y + dy, cost + 1, dist));
}
}
}
}
}
return list;
}
/******************************************************************
* removeFromList
* function used in pathfinding
******************************************************************/
private void removeFromList(Vector v, PathNode p) {
Enumeration e = v.elements();
while (e.hasMoreElements()) {
PathNode nn = (PathNode) e.nextElement();
if ((nn.x == p.x) && (nn.y == p.y)) {
v.removeElement(nn);
return;
}
}
}
/******************************************************************
* addToOpen
* function used in pathfinding
******************************************************************/
private void addToOpen(Vector open, int x, int y, double cost, double dist, PathNode parent) {
PathNode node = new PathNode(x, y, cost, dist);
node.parent = parent;
if (open.size() > 0) {
for (int i=0; i<open.size(); i++) {
PathNode p = (PathNode) open.elementAt(i);
if (p.cost > cost) {
open.insertElementAt(node, i);
return;
}
}
}
open.addElement(node);
}
/******************************************************************
* checkIfGot
* function used in pathfinding to avoid duplication of squares
******************************************************************/
private boolean checkIfGot(Vector v, PathNode p) {
Enumeration e = v.elements();
while (e.hasMoreElements()) {
PathNode nn = (PathNode) e.nextElement();
if ((nn.x == p.x) && (nn.y == p.y)) return true;
}
return false;
}
/******************************************************************
* findPath
* entry function used in pathfinding
******************************************************************/
public Vector findPath(int sx, int sy, int tx, int ty) {
Vector path = new Vector();
Vector open = new Vector();
Vector closed = new Vector();
int count = 0;
if ((sx == tx) && (sy == ty)) {
path.insertElementAt(new PathNode(tx, ty, 0, 0), 0);
return path;
}
double dist = range(sx, sy, tx, ty);
addToOpen(open, sx, sy, 0, dist, null);
while (!open.isEmpty())
{
PathNode pn = (PathNode) open.elementAt(0);
open.removeElementAt(0);
if ((pn.x == tx) && (pn.y == ty)) {
// path found
while (pn.parent != null)
{
path.insertElementAt(pn, 0);
pn = pn.parent;
}
return path;
}
// get neighbours
Vector neighbours = getNeighbours(pn.x, pn.y, pn.cost, tx, ty);
count++;
// check each neighbour
Enumeration e = neighbours.elements();
while (e.hasMoreElements())
{
PathNode nn = (PathNode) e.nextElement();
// check if in open & closed
boolean isInOpen = checkIfGot(open, nn);
boolean isInClosed = checkIfGot(closed, nn);
double cost = pn.cost + range(pn.x, pn.y, nn.x, nn.y);
if ((!isInOpen) && (!isInClosed) || (cost < nn.cost)) {
nn.parent = pn;
nn.cost = cost;
if (isInClosed) removeFromList(closed, nn);
addToOpen(open, nn.x, nn.y, nn.cost, nn.dist, nn.parent);
}
}
closed.addElement(pn);
}
return null;
}