我的探路器在寻找最短路径时遇到问题
我在寻路器方面遇到问题(这是我的第一个,所以这是可以预料的):它并不总是采取最短路线。例如,如果我想向下走一格,路径将是:向左一格,向下一格,向右一格。
public void getSquares(){
actPath = new String[Map.x][Map.y];
isDone = new boolean[Map.x][Map.y];
squareListener = new SquareListener[Map.x][Map.y];
getSquares2(x,y,0,new String());
}
public void getSquares2(int x, int y, int movesused, String path){
boolean test1 = false;
boolean test2 = false;
test1 = (x < 0 || y < 0 || x > Map.x || y > Map.y);
if(!test1){
test2 = Map.landTile[y][x].masterID != 11;
}
if(movesused <= 6 && (test1 || test2)){
addMoveSquare2(x,y, path);
getSquares2(x+1,y,movesused+1,path+"r");
getSquares2(x,y+1,movesused+1,path+"d");
getSquares2(x,y-1,movesused+1,path+"u");
getSquares2(x-1,y,movesused+1,path+"l");
}
}
public void addMoveSquare2(int x, int y, String path){
if(x >= 0 && y>=0 && x < Map.x && y < Map.y && (actPath[x][y] == null || actPath[x][y].length() > path.length())){
if(squareListener[x][y] == null){
actPath[x][y] = new String();
actPath[x][y] = path;
JLabel square = new JLabel();
square.setBounds(x*16,y*16,16,16);
square.setIcon(moveSquare);
squareListener[x][y] = new SquareListener(x,y,path);
square.addMouseListener(squareListener[x][y]);
Map.cases.add(square);
}
else{
squareListener[x][y].path = path;
}
}
}
SquareListener 是一个简单的 MouseListener,它打印方块的位置及其路径。 Map.x、Map.y 是地图大小。 getSquares2 以起点为起点调用,并绘制每 6 个移动距离的方块,并将每个值为“11”的情况视为障碍。
你能帮我找出我做错了什么吗?
这是结果的屏幕截图: http://img808.imageshack.us/img808/96/screen.gif 红色方块是可能的目标。只有当玩家单击一个方块时才会定义真正的方块(MouseListener 是 SquareListener,它应该知道要采取的路径)。房屋是值为“11”的情况,即障碍物。
I'm having problems with a pathfinder (it's my first, so that was to be expected) : it doesn't always take the shortest way. For example, if I want to go one square down, the path will be : one square left, one down, one right.
public void getSquares(){
actPath = new String[Map.x][Map.y];
isDone = new boolean[Map.x][Map.y];
squareListener = new SquareListener[Map.x][Map.y];
getSquares2(x,y,0,new String());
}
public void getSquares2(int x, int y, int movesused, String path){
boolean test1 = false;
boolean test2 = false;
test1 = (x < 0 || y < 0 || x > Map.x || y > Map.y);
if(!test1){
test2 = Map.landTile[y][x].masterID != 11;
}
if(movesused <= 6 && (test1 || test2)){
addMoveSquare2(x,y, path);
getSquares2(x+1,y,movesused+1,path+"r");
getSquares2(x,y+1,movesused+1,path+"d");
getSquares2(x,y-1,movesused+1,path+"u");
getSquares2(x-1,y,movesused+1,path+"l");
}
}
public void addMoveSquare2(int x, int y, String path){
if(x >= 0 && y>=0 && x < Map.x && y < Map.y && (actPath[x][y] == null || actPath[x][y].length() > path.length())){
if(squareListener[x][y] == null){
actPath[x][y] = new String();
actPath[x][y] = path;
JLabel square = new JLabel();
square.setBounds(x*16,y*16,16,16);
square.setIcon(moveSquare);
squareListener[x][y] = new SquareListener(x,y,path);
square.addMouseListener(squareListener[x][y]);
Map.cases.add(square);
}
else{
squareListener[x][y].path = path;
}
}
}
SquareListener is a simple MouseListener which print the square's location and the path to it.
Map.x, Map.y are the map size.
getSquares2 is called with the start point, and draw every squares that are 6 moves away, and consider every case with the value "11" as obstacle.
Can you please help me finding what I've done wrong ?
Here is a screenshot of the result :
http://img808.imageshack.us/img808/96/screen.gif
The red squares are the possible goal. The real one will be defined only when the player click on one square (the MouseListener being SquareListener, it's supposed to know the path to take). The houses are the cases with a value of "11", the obstacles.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的算法看起来几乎是正确的。几乎,因为当找到节点的第二条路径时,您忘记分配actPath[x][y],因此使用
actPath[x][y]
渲染长度检查不正确。你应该这样做:你的算法也有令人讨厌的时间复杂度,因为它将迭代长度为 6 的所有路径(所有 4^6 = 4096 个),而不是仅最短的路径(6*6 + 5*5 = 61
)灵感,我建议查看 Dijkstra 算法(A* 的前身),它管理当路径长度是小整数时,仅访问最短路径,并以 O(可达节点数)结束,就像这里的情况一样。
Your algorithm looks nearly correct. Nearly, because you forget to assign
actPath[x][y]
when a second path to the node is found, rendering your length check withactPath[x][y]
incorrect. You should do:Your algorithm also has abominable time complexity, as it will iterate all paths of length 6 (all 4^6 = 4096 of them) instead of the just the shortest ones (6*6 + 5*5 = 61)
For inspiration, I recommend looking at Dijkstra's algorithm (the precursor to A*), which manages to only visit the shortest paths and concludes in O(number of reachable nodes) when path lengths are small integers as it the case here.
您可以在此处查看我的答案,其中包含 A-Star 的示例代码,而不是直接的答案,但代码是可读的,它向您指出一本关于路径查找(以及其他许多事情)的好书。我从来没有抽出时间来评论代码......
不知道你的意思,在丹尼尔的评论中,“谢谢你的链接,但是,我没有一个目标,而是一些动作,这使得很多可能的目标。”
You can take a look here at my answer with example code for A-Star, not a direct answer but the code is readable and it points you to a good book that deals (among many other things) path finding. I never did get around to commenting the code...
Not sure what you mean, in the comment for Daniel, by "Thanks for the link, however, I don't have 1 goal but a number of moves, which makes a lot of possible goals."
您可能对此感兴趣 关于A* 搜索算法的教程。
You might be interested in this tutorial on the A* search algorithm.