/** * Determine the distance between two neighbor Cells * as used by the AStar algorithm. * * @param cell1 any Cell * @param cell2 any of cell1's neighbors * @return Float - the distance between the two neighbors */ public float getDistanceBetween(AStarCell cell1, AStarCell cell2) { //if the cells are on top or next to each other, return 1 if (cell1.getX() == cell2.getX() || cell1.getY() == cell2.getY()) { return(1);//*(mapHeight+mapWith); } else { //if they are diagonal to each other return diagonal distance: sqrt(1^2+1^2) return(SQRT2); //*(mapHeight+mapWith); } }
public List <Point> calcShortestPath(int startX, int startY, int goalX, int goalY) { AStarCell startCell = map.getCell(startX, startY); AStarCell goalCell = map.getCell(goalX, goalY); //Check if the start cell is also an obstacle (if it is, it is impossible to find a path) if (AStarCell.isObstacle(startCell)) { UnityEngine.Debug.Log("start is null"); return(null); } //Check if the goal cell is also an obstacle (if it is, it is impossible to find a path there) if (AStarCell.isObstacle(goalCell)) { UnityEngine.Debug.Log("end is null"); return(null); } startCell.reset(); startCell.setDistanceFromStart(0); closedList.Clear(); openList.Clear(); openList.Add(startCell); //while we haven't reached the goal yet while (openList.Count() != 0) { //get the first Cell from non-searched Cell list, sorted by lowest distance from our goal as guessed by our heuristic AStarCell current = openList[0]; // check if our current Cell location is the goal Cell. If it is, we are done. if (current.getX() == goalX && current.getY() == goalY) { return(reconstructPath(current)); } //move current Cell to the closed (already searched) list openList.Remove(current); closedList.Add(current); //go through all the current Cells neighbors and calculate if one should be our next step foreach (AStarCell neighbor in map.getNeighborList(current)) { bool neighborIsBetter; //if we have already searched this Cell, don't bother and continue to the next one if (closedList.Contains(neighbor)) { continue; } // calculate how long the path is if we choose this neighbor as the next step in the path float neighborDistanceFromStart = (current.getDistanceFromStart() + AStarMap.getDistanceBetween(current, neighbor)); //add neighbor to the open list if it is not there if (!openList.Contains(neighbor)) { neighbor.reset(); openList.Add(neighbor); neighborIsBetter = true; //if neighbor is closer to start it could also be better } else if (neighborDistanceFromStart < current.getDistanceFromStart()) { neighborIsBetter = true; } else { neighborIsBetter = false; } // set neighbors parameters if it is better if (neighborIsBetter) { neighbor.setPreviousCell(current); neighbor.setDistanceFromStart(neighborDistanceFromStart); neighbor.setHeuristicDistanceFromGoal(heuristic.getEstimatedDistanceToGoal( neighbor.getX(), neighbor.getY(), goalCell.getX(), goalCell.getY())); // csharp List.Sort use QuickSort, which is unstable, // but in java implement ArrayList.sort use MergeSort, which is stable, // so here use MergeSort to generate the same result as in java implement MergeSortClass.MergeSort(openList); } } } UnityEngine.Debug.Log("path is null"); return(null); }
public List <AStarCell> getNeighborList(AStarCell cell) { List <AStarCell> neighborList = new List <AStarCell>(); bool downWalkable = false; if (cell.getY() > 0) {// down AStarCell neighbor = getCell(cell.getX(), (cell.getY() - 1)); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); downWalkable = true; } } bool rightWalkable = false; if (cell.getX() < (widthInCells - 1)) {// right AStarCell neighbor = getCell(cell.getX() + 1, cell.getY()); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); rightWalkable = true; } } bool upWalkable = false; if (cell.getY() < (heightInCells - 1)) {// up AStarCell neighbor = getCell(cell.getX(), cell.getY() + 1); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); upWalkable = true; } } bool leftWalkable = false; if (cell.getX() > 0) {// left AStarCell neighbor = getCell(cell.getX() - 1, cell.getY()); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); leftWalkable = true; } } if (downWalkable || rightWalkable) { if (cell.getX() < (widthInCells - 1) && cell.getY() > 0) {// down right AStarCell neighbor = getCell(cell.getX() + 1, cell.getY() - 1); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); } } } if (upWalkable || rightWalkable) { if (cell.getX() < (widthInCells - 1) && cell.getY() < (heightInCells - 1)) { // up right AStarCell neighbor = getCell(cell.getX() + 1, cell.getY() + 1); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); } } } if (upWalkable || leftWalkable) { if (cell.getX() > 0 && cell.getY() < (heightInCells - 1)) {// up left AStarCell neighbor = getCell(cell.getX() - 1, cell.getY() + 1); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); } } } if (downWalkable || leftWalkable) { if (cell.getX() > 0 && cell.getY() > 0) {// down left AStarCell neighbor = getCell(cell.getX() - 1, cell.getY() - 1); if (!AStarCell.isObstacle(neighbor)) { neighborList.Add(neighbor); } } } return(neighborList); }