两次迭代后,A *算法停止

时间:2016-11-09 15:45:53

标签: java algorithm while-loop path-finding breadth-first-search

我已经写了一个A *算法来找到从敌人到玩家的最短路径(敌人只能在4个基本方向上移动),但是,只有起始单元格和周围的4个单元格被添加到打开列表,然后算法停止。如果有人可以查看我的代码来找到我可能错过的东西,那将是值得赞赏的。谢谢! 作为参考,放在打开列表中的单元格在图片中显示为红色: http://imgur.com/a/sMbzL

主要搜索类:

import acm.util.*;
import java.awt.*;
import java.util.*;

/**
* searches to find the shortest path between two points
* 
* @author Garrett Rademacher
* @version 1.0
*/
public class AStarMain
{
// instance variables
private ArrayList<AStarCell> open = new ArrayList<AStarCell>(); //list of open cells
private ArrayList<AStarCell> closed = new ArrayList<AStarCell>();//list of closed cells
public ArrayList<Character> path = new ArrayList<Character>(); //will hold the path once found
public static AStarCell[][] grid = new AStarCell[25][25]; //grid of cells
private int startRow, startCol; //staring point for the search
private int endRow, endCol; //destination
private boolean pathFound = false;
private AStarCell current; //current cell
private HackNSlashMain game;

public AStarMain(int startRow, int startCol, int endRow, int endCol, HackNSlashMain game){
    //save passed data
    this.startRow = startRow;
    this.startCol = startCol;
    this.endRow = endRow;
    this.endCol = endCol;
    this.game = game;

    //populate grid
    populateGrid();

    //start main pathfinding method
    open.add(0, grid[startRow][startCol]); //add the starting cell to the open list
    current = grid[startRow][startCol]; //set the current cell to the starting cell

    //use a while loop to search for a path
    while(!pathFound && open.size()>0){
        //loop through the open array list, find the cell with the lowest cost
        for(int i = 0; i < open.size(); i++){
            if(open.get(i).getFCost() < current.getFCost() && open.get(i).getFCost() != 0){
                current = open.get(i);
            }
            game.cell[open.get(i).getRow()][open.get(i).getCol()].colorRed();
        }
        //remove the found cell from the open list
        open.remove(current);
        //add the cell to the closed list
        closed.add(current);

        //check if a path has been found
        if(current.getRow() == endRow && current.getCol() == endCol){
            pathFound = true;
            constructPath();
        }

        //consider each vertical and horizontal neighbor of the current cell
        //check if in bounds of array of cells
        if(checkInBounds(current.getRow()-1, current.getCol())){
            consider(grid[current.getRow()-1][current.getCol()]);
        }
        if(checkInBounds(current.getRow()+1, current.getCol())){
            consider(grid[current.getRow()+1][current.getCol()]);
        }
        if(checkInBounds(current.getRow(), current.getCol()-1)){
            consider(grid[current.getRow()][current.getCol()-1]);
        }
        if(checkInBounds(current.getRow(), current.getCol()+1)){
            consider(grid[current.getRow()][current.getCol()+1]);
        }
    }
}

private void consider(AStarCell passedCell){
    //if the neighbor cell is not passable or is already on the closed list, skip it
    if(!passedCell.getIsPassable() || closed.contains(passedCell)){
        return;
    }

    //calculate the h cost of the cell
    int heuristic = (Math.abs(endRow-passedCell.getRow()) + Math.abs(endCol-passedCell.getCol()));
    passedCell.setHCost(heuristic);
    //calculate the g cost (add one to the g cost of the current cell)
    int holdingGCost = current.getGCost() + 1;

    //if the cell has not been touched before, or if accesing the cell via current is a shorter route
    if(passedCell.getGCost() > holdingGCost || !(passedCell.getGCost() == 0)){
        //set the gCost
        passedCell.setGCost(holdingGCost);
        //set the f cost to gCost + hCost
        passedCell.calcFCost();
        //set the parent cell of passedCell to current cell
        passedCell.setParent(current);
    }

    //if the passedCell does not exist in the open list
    if(!(open.contains(passedCell))){
        //add passedCell to open
        open.add(passedCell);
    }

}

private boolean checkInBounds(int row, int col){
    if(row > -1 && row < 25 && col > -1 && col < 25){return true;} //cell is in bounds
    else{return false;}//cell is out of bounds
}

private void constructPath(){
    //once a path has been found, trace it backwards adding each step to the path ArrayList
    //start at the end cell,
    AStarCell currentCell = grid[endRow][endCol];
    AStarCell parentCell;
    while(!(currentCell.getRow() == startRow) && !(currentCell.getCol() == startCol)){
        parentCell = currentCell.getParent(); //get the parent cell
        if((parentCell.getRow()) < (currentCell.getRow())){
            //add move up
            Character character = new Character('U');
            path.add(0,character);
        }else if((parentCell.getRow()) > (currentCell.getRow())){
            //add move down
           Character character = new Character('D');
            path.add(0,character);
        }else if((parentCell.getCol()) > (currentCell.getCol())){
            //add move left
            Character character = new Character('L');
            path.add(0,character);
        }else if((parentCell.getCol()) < (currentCell.getCol())){
            //add move right
            Character character = new Character('R');
            path.add(0,character);
        }
        currentCell = parentCell;//update the current cell so the path traces backwards
    }
}

public Character getMove(){
    return path.get(0);
}

private void populateGrid(){
    for(int i = 0; i < 25; i++){
        for(int j = 0; j < 25; j++){
            AStarCell cell = new AStarCell(i,j);
            grid[i][j] = cell;
            cell.setPassable(game.cell[i][j].getIsPassable());
        }
    }
}
}

细胞类:

public class AStarCell
{   
// instance variables
private int hCost = 0;
private int gCost = 0;
private int fCost = 0; //G+H
private int row, col; //location in grid of cells
private AStarCell parent; //parent cell
private boolean isPassable = true;


AStarCell(int row, int col){
    this.row = row;
    this.col = col;
}

public void setGCost(int gCost){
    this.gCost = gCost;
}

public void setHCost(int hCost){
    this.hCost = hCost;
}

public void calcFCost(){
    fCost = gCost + hCost;
}

public void setParent(AStarCell parentCell){
    this.parent = parentCell;
}

public void setPassable(boolean isPassable){
    this.isPassable = isPassable;
}

public int getGCost(){
    return this.gCost;
}

public int getFCost(){
    return fCost;
}

public boolean getIsPassable(){
    return isPassable;
}

public int getCol(){
    return col;
}

public int getRow(){
    return row;
}

public AStarCell getParent(){
    return this.parent;
}

}

我也在使用ACM库,如果这有助于消除任何混淆。

0 个答案:

没有答案