私は A* パスファインディング アルゴリズムに取り組んでいますが、何らかの理由で特定の時点で null ポインター例外が発生し、その理由がわかりません。この問題は、H 値の単純な seter であるクラス Astar 行 79 で発生します。
Astar クラスは次のとおりです。
import java.util.*;
public class Astar {
private int[][] map;
private int Infinity = Integer.MAX_VALUE;
private GridElement startElement;
private GridElement endElement;
private GridElement[][] grid;
private int currentX;
private int currentY;
private int tmpV;
private int adjacentX;
private int adjacentY;
//private int x;
//private int y;
private GridElement adjacentE;
private GridElement adjacentW;
private GridElement adjacentN;
private GridElement adjacentS;
public Astar(int[][] map, int xStart, int yStart, int xEnd, int yEnd) {
this.map= map;
grid = new GridElement[map.length][map[0].length];
for(int i=0;i<grid.length;i++)
for(int j=0;j<grid[0].length;j++){
grid[i][j]=new GridElement(i,j,map[i][j],grid);
grid[i][j].setG(map[i][j]);}
this.startElement=grid[xStart][yStart];
this.endElement=grid[xEnd][yEnd];
}
public void AstarAlgortihm() {
ArrayList<GridElement> openList = new ArrayList<GridElement>();
for(int i=0;i<grid.length;i++)
for(int j=0;j<grid[0].length;j++)
openList.add(grid[i][j]);
GridElement current = startElement;
GridElement next;
while(openList.isEmpty() == false){
openList.remove(current);
current.setVisited(true);
if(current==endElement)
break;
int northF=Infinity;
int southF=Infinity;
int westF=Infinity;
int eastF=Infinity;
if(current.hasNeighbour(1,0)!=null && grid[current.getX()+1][current.getY()].checkVisited() == false) {
adjacentS = current.hasNeighbour(1,0);
grid[current.getX()+1][current.getY()].setParent(current);
adjacentS.setH(H(current.getX()+1, current.getY()));
adjacentS.setF();
southF=adjacentS.getF();}
if(current.hasNeighbour(-1,0)!=null && grid[current.getX()-1][current.getY()].checkVisited()==false) {
adjacentN = current.hasNeighbour(-1,0);
grid[current.getX()-1][current.getY()].setParent(current);
adjacentN.setH(H(current.getX()-1, current.getY()));
adjacentN.setF();
northF=adjacentN.getF();}
if(current.hasNeighbour(0,1)!=null && grid[current.getX()][current.getY()+1].checkVisited()==false) {
adjacentE = current.hasNeighbour(1,0);
grid[current.getX()][current.getY()+1].setParent(current);
adjacentE.setH(H(current.getX(), current.getY()+1));
adjacentE.setF();
eastF=adjacentE.getF();}
if(current.hasNeighbour(0,-1)!=null && grid[current.getX()][current.getY()-1].checkVisited()==false) {
adjacentW = current.hasNeighbour(1,0);
grid[current.getX()][current.getY()-1].setParent(current);
adjacentW.setH(H(current.getX(), current.getY()-1));
adjacentW.setF();
westF=adjacentW.getF();}
if(northF <southF &&northF < westF &&northF< eastF){
current=adjacentN;
}
else if(eastF<southF && eastF< northF && eastF < westF){
current=adjacentE;
}
else if(westF < southF && westF < northF && westF<eastF){
current = adjacentW;
}
else
current=adjacentS;
}
if(current==endElement) {
while(current != startElement){
current.setIsPathmember(true);
current= current.getParent();
}
current.setIsPathmember(true);
} else System.out.println("No path found");
}
public int[][] getMap(){
int[][] tempmap = new int[grid.length][grid[0].length];
for(int i=0;i<grid.length;i++)
for(int j=0;j<grid[0].length;j++)
if(grid[i][j].getIsPathMember())
tempmap[i][j]=9;
else
tempmap[i][j]=grid[i][j].getCost();
return tempmap;
}
public int H(int x, int y){
int xCoords=(endElement.getX())- x ;
int yCoords=(endElement.getY()) - y ;
return xCoords+yCoords;
}
}
そして、これが GridElement クラスです。これは、Dijkstra のアルゴリズムの GridElement calss でもあるため、Astar にあるべきではないものがある場合は、それが理由です。
public class GridElement {
private int x;
private int y;
private int value;
private boolean isVisited;
private GridElement parent;
private int cost;
private boolean isWall;
private GridElement[][] map;
private boolean isPathMember;
private int g;
private int h;
private int f;
public GridElement(int x, int y, int cost, GridElement[][] map) {
this.x=x;
this.y=y;
this.isPathMember=false;
this.isVisited=false;
this.parent=null;
this.value=Integer.MAX_VALUE;
if(cost==0)
this.isWall=true;
else
this.isWall=false;
this.cost = cost;
this.map = map;
}
public int getX() {
return x;
}
public int getY(){
return y;
}
public void setValue(int v){
this.value=v;
}
public boolean checkVisited(){
return isVisited;
}
public int getValue(){
return value;
}
public void setParent(GridElement p){
this.parent=p;
}
public GridElement getParent(){
return parent;
}
public boolean checkWall(){
return isWall;
}
public void setVisited(boolean v){
this.isVisited=v;
}
public void setIsPathmember(boolean is) {
this.isPathMember = is;
}
public boolean getIsPathMember(){
return isPathMember;
}
public int getCost(){
return cost;
}
public void setG(int g){
this.g=g;
}
public void setH(int h){
this.h=h;
}
public void setF(){
this.f=g+h;
}
public int getF(){
return f;
}
public int getH(){
return h;
}
public int getG(){
return g;
}
public String toString() {
String tempString="";
tempString+="Node: "+getX()+","+getY()+","+getValue()+"|||";
return tempString;
}
public GridElement hasNeighbour(int horizontalShift, int verticalShift){ // Params will be -+1
if(getX()+horizontalShift>=0 && getX()+horizontalShift<map.length && getY()+verticalShift>=0 && getY()+verticalShift<map[0].length)
if(!map[getX()+horizontalShift][getY()+verticalShift].checkWall())
if(!map[getX()+horizontalShift][getY()+verticalShift].checkVisited())
return map[getX()+horizontalShift][getY()+verticalShift];
return null;
}
}
null ポインターが「存在する可能性がある」理由はわかりますが、最初に if ステートメントでそれを処理するべきではありませんか? 前もって感謝します!