So I think I am closer to actual A* pathfinding. However, you can see the current path in the image below
Pathfinder code:
public class Pathfinder {
private TileMap map;
public Pathfinder(TileMap map){
this.map = map;
}
private ArrayList<ITile> open = new ArrayList<ITile>();
private ArrayList<ITile> closed = new ArrayList<ITile>();
public Path getPath(int tx, int ty, int sx, int sy){
long before = System.currentTimeMillis();
int ax = sx, ay = sy; // active tiles
Path path = new Path();
ITile active = map.getTile(ax, ay);
open.add(active);
path.addTile(active);
while(!(ax == tx && ay == ty) || open.size() == 0){ // continue until the path has been completed or there are no possible tiles left
// Get the surrounding tiles
ITile topleft = map.getTile(ax - 1, ay - 1);
if(topleft != null) topleft.setParent(active);
ITile top = map.getTile(ax, ay - 1);
if(top != null) top.setParent(active);
ITile topright = map.getTile(ax + 1, ay - 1);
if(topright != null) topright.setParent(active);
ITile left = map.getTile(ax - 1, ay);
if(left != null) left.setParent(active);
ITile right = map.getTile(ax + 1, ay);
if(right != null) right.setParent(active);
ITile bottomleft = map.getTile(ax - 1, ay + 1);
if(bottomleft != null) bottomleft.setParent(active);
ITile bottom = map.getTile(ax, ay + 1);
if(bottom != null) bottom.setParent(active);
ITile bottomright = map.getTile(ax + 1, ay + 1);
if(bottomright != null) bottomright.setParent(active);
// Swap out the tiles
if(topleft != null && topleft.weight < 100 && available(topleft)){
open.add(topleft);
}
if(top != null && top.weight < 100 && good(top)){
open.add(top);
}
if(topright != null && topright.weight < 100 && good(topright)){
open.add(topright);
}
if(left != null && left.weight < 100 && good(left)){
open.add(left);
}
if(right != null && right.weight < 100 && good(right)){
open.add(right);
}
if(bottomleft != null && bottomleft.weight < 100 && good(bottomleft)){
open.add(bottomleft);
}
if(bottom != null && bottom.weight < 100 && good(bottom)){
open.add(bottom);
}
if(bottomright != null && bottomright.weight < 100 && good(bottomright)){
open.add(bottomright);
}
// Get their values
double topleftF = F(sx, sy, tx, ty, ax, ay);
double topF = F(sx, sy, tx, ty, ax, ay);
double toprightF = F(sx, sy, tx, ty, ax, ay);
double leftF = F(sx, sy, tx, ty, ax, ay);
double rightF = F(sx, sy, tx, ty, ax, ay);
double bottomleftF = F(sx, sy, tx, ty, ax, ay);
double bottomF = F(sx, sy, tx, ty, ax, ay);
double bottomrightF = F(sx, sy, tx, ty, ax, ay);
// Determine the lowest step
double min = min(topleftF, topF, toprightF, leftF, rightF, bottomleftF, bottomF, bottomrightF);
if(check(min, topleftF) && available(topleft)){
active = topleft;
}
else if(check(min, topF) && available(top)){
active = top;
}
else if(check(min, toprightF) && available(topright)){
active = topright;
}
else if(check(min, leftF) && available(left)){
active = left;
}
else if(check(min, rightF) && available(right)){
active = right;
}
else if(check(min, bottomleftF) && available(bottomleft)){
active = bottomleft;
}
else if(check(min, bottomF) && available(bottom)){
active = bottom;
}
else if(check(min, bottomrightF) && available(bottomright)){
active = bottomright;
}
// Remove the tiles
ax = active.tx;
ay = active.ty;
swap(active);
// Add the step
path.addTile(active);
}
// Add the target tile
path.addTile(map.getTile(tx, ty));
long after = System.currentTimeMillis();
path.setOverall(map.getTile(sx, sy), map.getTile(tx, ty));
path.setMillis(after - before);
return path;
}
// -------------[ UTILITIES ]-------------
private void swap(ITile tile){
if(tile == null) return;
open.remove(tile);
closed.add(tile);
}
private boolean good(ITile tile){
if(tile == null) return false;
return !closed.contains(tile);
}
private boolean available(ITile tile){
if(tile == null) return false;
if(!open.contains(tile)){
return false;
}
if(closed.contains(tile)){
return false;
}
return open.contains(tile) && !closed.contains(tile);
}
private boolean check(double min, double F){
return min == F;
}
private double min(double... doubles){
double min = 1000000;
for(double double_ : doubles){
min = Math.min(double_, min);
}
return min;
}
private double F(int sx, int sy, int tx, int ty, int ax, int ay){
if(ax < 0 || ay < 0 || ay >= map.getHeight() || ax >= map.getWidth()){
return 1000;
}
double G = Math.sqrt((ax - sx) * (ax - sx) + (ay - sy) * (ay - sy));
double H = Math.abs(tx - ax) + Math.abs(ty - ay);
double F = G + H;
return map.getTile(ax, ay).weight * F; // Multiply by the weight of the tile
}
}
CopyableCougar4