【发布时间】:2017-08-26 11:28:27
【问题描述】:
我是新手,遇到这么尴尬的问题:
.
算法似乎吞噬了一个额外的十六进制。 有人能指出我的错误吗?
代码如下:
(出现在1和2中的'ob'是一组'障碍')
1.寻路功能:
private static Node pathFinding(Vector2i startHex, Vector2i goalHex, HashSet<Vector2i> ob, int movesLeft) {
start = new Node(startHex);
goal = new Node(goalHex);
if (distance(start, goal) > movesLeft) return null;
TreeSet<Node> openSet = new TreeSet<>(new NodeComparator());
HashSet<Node> closedSet = new HashSet<>();
start.cameFrom = null;
start.g = 0;
start.h = distance(start, goal);
start.f = start.g + start.h;
openSet.add(start);
float tentativeScore;
while (!openSet.isEmpty()) {
current = openSet.pollFirst();
if (current.coords.equals(goal.coords)) {
return current;
}
closedSet.add(current);
for (Node node : getNeighbors(current, ob)) {
node.g = distance(start, node);
tentativeScore = current.g + distance(current, node);
if (!closedSet.contains(node) || tentativeScore < node.g) {
node.g = tentativeScore;
node.h = distance(node, goal);
node.f = node.g + node.h;
node.cameFrom = current;
openSet.add(node);
}
}
}
return null;
}
2.邻居:
private static final Vector2i[] directions2i = {
new Vector2i(0,-1), new Vector2i(1,-1), new Vector2i(1,0),
new Vector2i(0,1), new Vector2i(-1,1), new Vector2i(-1,0)
};
private static List<Node> getNeighbors(Node origin, HashSet<Vector2i> ob) {
List<Node> list = new ArrayList<>();
for (int i = 0; i < 6; i++) {
Vector2i dir = new Vector2i(origin.coords.x + directions2i[i].x, origin.coords.y + directions2i[i].y);
if (!ob.contains(dir))
list.add(new Node(dir));
}
return list;
}
3.启发式:
static float distance(Node a, Node b) {
return (Math.abs(a.coords.x - b.coords.x) + Math.abs(a.coords.y - b.coords.y) + Math.abs(a.coords.x +a.coords.y -b.coords.x -b.coords.y)) / 2;
}
4. 以防万一这里是 Node 和 Comparator 类:
public class Node {
public Node cameFrom;
public Vector2i coords;
float g, h, f;
@Override
public int hashCode() {
return coords.x * 100000 + coords.y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (getClass() != o.getClass()) return false;
Node oth = (Node) o;
return this.coords.equals(oth.coords);
}
Node(Vector2i coords) {
this.coords = new Vector2i(coords);
}
}
private static class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
return Float.compare(o1.f, o2.f);
}
}
【问题讨论】:
-
不是答案,而是:代码有点难以阅读和理解,尤其是很难仅仅通过查看来“调试”。但以防万一你自己没有找到它:redblobgames.com/grids/hexagons 上有一个关于六边形网格的优秀资源(包括邻居搜索、距离计算,甚至有障碍物的路径查找)
-
openSet.add是否返回false? -
@Marco13 感谢您提供有用的信息!
-
@harold 我想是的。每次 set 已经包含该元素时,它都会返回 false
-
这很糟糕,这意味着您不会更新您找到更好路线的节点的父/G。您可以尝试在添加之前删除节点。
标签: java algorithm path-finding a-star hexagonal-tiles