我大胆尝试学习并在游戏中实现这个算法,“理解”它相对容易。但在实现过程中,我一直遇到一个无法退出的无限循环。我反复检查了代码,但肯定遗漏了一些东西,或者没有理解某些部分。 任何帮助将不胜感激。
public class PathFinder {private LinkedList<Node> openList;private LinkedList<Node> closedList;public PathFinder() { openList = new LinkedList<Node>(); closedList = new LinkedList<Node>();}private List<Node> buildPath(Node node) { LinkedList<Node> path = new LinkedList<Node>(); while (node.parentNode != null) { path.addFirst(node); node = node.parentNode; } return path;}public List<Node> findPath(int sx, int sy, int dx, int dy) { Node startNode = new Node(sx, sy); Node endNode = new Node(dx, dy); startNode.costG = 0; startNode.costH = startNode.getManhattanCost(endNode); startNode.parentNode = null; openList.add(startNode); while (!openList.isEmpty()) { Node currentNode = (Node) openList.removeFirst(); if (currentNode == endNode) { Log.d("android", "found path"); return buildPath(endNode); } else { currentNode.createNeighbors(); List<Node> neighbors = currentNode.getNeighbors(); for (int i = 0; i < neighbors.size(); i++) { Node neighborNode = neighbors.get(i); neighborNode.costG += currentNode.costG; neighborNode.costH = neighborNode.getManhattanCost(endNode); neighborNode.costF = neighborNode.costG + neighborNode.costH; boolean isInOpen = openList.contains(neighborNode); boolean isInClosed = closedList.contains(neighborNode); if ((!isInOpen && !isInClosed) || neighborNode.costG < currentNode.costG) { neighborNode.parentNode = currentNode; neighborNode.costG += currentNode.costG; neighborNode.costF = neighborNode.costG + neighborNode.costH; if (isInClosed) { closedList.remove(neighborNode); } if (!isInOpen) { openList.add(neighborNode); } } } closedList.add(currentNode); } } openList.clear(); closedList.clear(); return null;}
}
public class Node {public Node parentNode;public List<Node> neighbors;public int x;public int y;public int costG;public int costH;public int costF;public Node(int x, int y) { this.x = x; this.y = y; neighbors = new ArrayList<Node>(); costG = 10;}public void createNeighbors() { neighbors.add(new Node(x + 1, y)); neighbors.add(new Node(x, y + 1)); neighbors.add(new Node(x - 1, y)); neighbors.add(new Node(x, y - 1));}public int getManhattanCost(Node node) { int i = (int) Math.abs(x - node.x); int j = (int) Math.abs(y - node.y); costH = i + j; return costH;}public int getTotalCost() { return costG + costH;}public List<Node> getNeighbors() { return neighbors;}
}
sx, sy, dx 和 dy 是二维数组中起始位置和目标位置。为了测试,我传入了固定的数字 sx = 1, sy = 1, dx = 5, dy = 5。换句话说,角色在 (1, 1) 处,触摸点在 (5, 5) 处。
回答:
经过大量努力后解决:在设置 currentNode 之后,清除 openList。