I am trying to solve my A * Path search algorithm. I have three classes Menu, Gridand Node.
If you run my program, you will see that it prints an unusual spiral, bouncing, bouncing rabbit path. I believe that unexpected behavior has something to do with the following function:
printAStarPath(int startx, int starty, int endx, int endy)
In my opinion, I think that the problem is due to the incorrect assignment of parent nodes. I am sure that Nodethey Menuare working correctly.
Input:
The menu function mainly controls user input. The user can add walls, start location and end location, as well as grid size. I also included some tests in the menu (so you do not always have the type all over again every time you check). The function printAStarPath(...)accepts the starting location x, y and the location of the end x, y.
Conclusion:
I want this to print the grid as follows:
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][ ]
[ ][S][ ][X][ ][E][ ]
[ ][ ][*][X][*][ ][ ]
[ ][ ][ ][*][ ][ ][ ]
Unfortunately, I get this madness:
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][*]
[ ][S][ ][X][ ][E][*]
[ ][ ][*][X][ ][ ][*]
[ ][ ][ ][*][*][*][ ]
Another example of what happens with another input:
[E][ ][ ][ ][ ]
[ ][*][ ][ ][*]
[ ][ ][X][ ][*]
[ ][ ][ ][ ][*]
[ ][*][ ][*][S]
Some of my grids look like arrows pointing down-right. Some look as if they are going down, and then spiral up and to the left.
Summary:
A *, ( H-) . G, .
, .
:
Menu:
package pathFinding;
import java.util.*;
public class Menu {
private Grid board;
public Menu(){
board = new Grid(0, 0);
}
static public void main (String[] args){
Menu pft = new Menu();
pft.boardMenu();
System.out.print("process terminated.");
}
public void boardMenu(){
boolean kg = true;
Scanner in = new Scanner(System.in);
int input;
while(kg){
input = -1;
System.out.print("\n\n\n\n");
System.out.print(">>> Hi there,"
+ "\n(0) quit"
+ "\n(1) test 1"
+ "\n(2) test 2"
+ "\n(3) new board"
+ "\n>>> ");
input = in.nextInt();
if (input == 3){
this.initUserData();
} else if (input == 0){
kg = false;
} else if (input == 1){
board.setSize(7, 5);
board.setCollidable(3, 1);
board.setCollidable(3, 2);
board.setCollidable(3, 3);
board.printAStarPath(1, 2, 5, 2);
} else if (input == 2){
board.setSize(25, 25);
board.setCollidable(5, 4);
board.setCollidable(4, 5);
board.setCollidable(3, 3);
board.printAStarPath(15, 15, 4, 4);
}
}
}
public void initUserData(){
boolean kgTmp = true;
int xTmp, yTmp, iTmp, jTmp = 0;
Scanner in = new Scanner(System.in);
System.out.print("\nBoard width: ");
xTmp = in.nextInt();
System.out.print("\nBoard height: ");
yTmp = in.nextInt();
board.setSize(xTmp, yTmp);
kgTmp = true;
while(kgTmp){
System.out.print("\nObstruction x Loc: ");
xTmp = in.nextInt();
System.out.print("\nObstruction y Loc: ");
yTmp = in.nextInt();
board.setCollidable(xTmp, yTmp);
System.out.print("\nMore Obstructions?(0=no;1=yes): ");
if(in.nextInt() == 0)
kgTmp = false;
}
System.out.print("\nStart x Loc: ");
xTmp = in.nextInt();
System.out.print("\nStart y Loc: ");
yTmp = in.nextInt();
System.out.print("\nEnd x Loc: ");
iTmp = in.nextInt();
System.out.print("\nEnd y Loc: ");
jTmp = in.nextInt();
System.out.println("\nredy for astar");
board.printAStarPath(xTmp, yTmp, iTmp, jTmp);
System.out.println("\nastar shud be done?");
}
}
Grid:
package pathFinding;
import java.util.*;
public class Grid {
private List<List<Node>> grid;
List<List<Integer>> path;
private int width;
private int height;
public Grid(int width, int height){
grid = new ArrayList<List<Node>>();
path = new ArrayList<List<Integer>>();
this.width = width;
this.height = height;
initGrid(width, height);
}
public void initGrid(int w, int h){
for (int i=0;i<w;i++)
grid.add(new ArrayList<Node>());
for (int i=0;i<w;i++)
for (int j=0;j<h;j++)
grid.get(i).add(new Node(i, j));
}
public void setSize(int w, int h){
this.width = w;
this.height = h;
clearAll();
initGrid(width, height);
}
public void clearAll(){
grid.clear();
path.clear();
}
public void printGrid(){
for (int j=0;j<height;j++){
for (int i=0;i<width;i++)
grid.get(i).get(j).printText();
System.out.println();
}
}
public void setCollidable(int x, int y){
grid.get(x).get(y).setCollidable(true);
grid.get(x).get(y).setText("[X]");
}
public void printAStarPath(int startx, int starty, int endx, int endy){
List<List<Integer>> closedList = new ArrayList<List<Integer>>();
List<List<Integer>> openList = new ArrayList<List<Integer>>();
int x = startx;
int y = starty;
int gOrig = 0;
int gThru = 0;
boolean condition = false;
if (closedList.contains(Arrays.asList(x, y)) == false)
closedList.add(Arrays.asList(x, y));
for (int i=x-1;i<x+2;i++){
for (int j=y-1;j<y+2;j++){
if (i>=0 && i<this.width){
if (j>=0 && j<this.height){
if (closedList.contains(Arrays.asList(i, j)) == false){
if (grid.get(i).get(j).getCollidable() == false){
grid.get(i).get(j).setParent( grid.get(x).get(y) );
openList.add(Arrays.asList(i, j));
}
}
}
}
}
}
while(condition == false){
x = getLowestFCostNodePos(openList, endx, endy)[0];
y = getLowestFCostNodePos(openList, endx, endy)[1];
closedList.add(Arrays.asList(x, y));
openList.remove(Arrays.asList(x, y));
for (int i=x-1;i<x+2;i++){
for (int j=y-1;j<y+2;j++){
if (i>=0 && i<this.width){
if (j>=0 && j<this.height){
if (closedList.contains(Arrays.asList(i, j)) == false){
if (grid.get(i).get(j).getCollidable() == false){
if (openList.contains(Arrays.asList(i, j)) == false){
grid.get(i).get(j).setParent( grid.get(x).get(y) );
openList.add(Arrays.asList(i, j));
}
else{
gOrig = grid.get(i).get(j).getG();
grid.get(i).get(j).setParent(grid.get(x).get(y));
gThru = grid.get(i).get(j).getG();
if (gOrig < gThru){
grid.get(i).get(j).setParent(grid.get(x).get(y).getParent());
}
openList.add(Arrays.asList(i, j));
}
}
}
}
}
}
}
if (openList.size() == 0){
condition = true;
System.out.print("\nNo Path.\n");
} else if (closedList.contains(Arrays.asList(endx, endy)) == true){
condition = true;
System.out.print("\nPath Found.\n");
}
}
if (openList.size() > 0)
getNodePath(grid.get(endx).get(endy));
if (openList.size() > 0)
for (int i=0; i<path.size(); i++){
grid.get(path.get(i).get(0)).get(path.get(i).get(1)).setText("[*]");
}
grid.get(startx).get(starty).setText("[S]");
grid.get(endx).get(endy).setText("[E]");
printGrid();
}
public void getNodePath(Node node){
if (node.getParent() != null){
this.path.add(0, Arrays.asList(node.getX(), node.getY()));
getNodePath(node.getParent());
}
}
public int[] getLowestFCostNodePos(List<List<Integer>> openList, int endx, int endy){
int xTmp = 0;
int yTmp = 0;
int fMin = 1000000;
int[] cords = new int[2];
for (int i=0;i<openList.size();i++){
xTmp = openList.get(i).get(0);
yTmp = openList.get(i).get(1);
if (fMin > grid.get(xTmp).get(yTmp).getF(endx, endy)){
fMin = grid.get(xTmp).get(yTmp).getF(endx, endy);
}
}
if (openList.size() > 0){
cords[0] = xTmp;
cords[1] = yTmp;
return cords;
} else{
System.out.print("openList is empty!");
return null;
}
}
}
Node:
package pathFinding;
public class Node {
private String text;
private int x;
private int y;
private boolean collidable;
private Node parent;
public Node(int x, int y){
text = "[ ]";
this.x = x;
this.y = y;
collidable = false;
parent = null;
}
public void setText(String text){
this.text = text;
}
public int getX(){
return this.x;
}
public int getY(){
return this.y;
}
public void setCollidable(boolean arg0){
collidable = arg0;
}
public boolean getCollidable(){
return collidable;
}
public void setParent(Node n){
parent = n;
}
public Node getParent(){
return parent;
}
public void printText(){
System.out.print(this.text);
}
public int getF(int endx, int endy){
return this.getG() + this.getH(endx, endy);
}
public int getG(){
if (parent != null){
if (parent.getX()-this.x == 0 || parent.getY()-this.y == 0)
return parent.getG() + 10;
else
return parent.getG() + 14;
}
return 0;
}
public int getH(int endx, int endy){
return (Math.abs(this.x-endx) + Math.abs(this.y-endy))*10;
}
}
EDIT:
, , , , :
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][X][ ][ ][ ][ ]
[ ][ ][X][X][X][X][ ][*][ ][ ]
[ ][ ][*][*][E][X][ ][ ][*][ ]
[ ][*][X][X][X][X][ ][ ][ ][S]
[ ][ ][*][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][*][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][*][ ][*][ ][ ][ ]
[ ][ ][ ][ ][ ][*][ ][ ][ ][ ]
- , ?