我正在开发一个带有 2d 数组作为包含节点的游戏地图的游戏。长宽不一样。这些节点有一个字段类型,需要不同的移动量才能到达。 A 需要一个,B 需要两个,C 无法到达。当我访问节点时,我将访问的属性设置为 true,但如果没有其他路径可用,则应使用访问的节点。我想将移动值存储在队列中,以便我可以在下一轮中对其进行轮询。如何找到从源到目标的最短路径并为其重用访问过的节点?我已经阅读了一些关于寻找网格中最后一个元素的最短路径的指南,但我的目标可以是任何地方。
到目前为止我的代码:
public class Node {
int x;
int y;
FieldType type;
boolean visited;
}
public enum FieldType {
A,B,C
}
public enum Move {
UP,
DOWN,
LEFT,
RIGHT
}
public class Test {
Queue<Move> queue;
Node[][] grid;
public Test(int l, int w, Node src, Node target) {
queue = new LinkedList<>();
grid = createGrid(l, w);
}
public Move getNextMove(Node src, Node target) {
if(queue.isEmpty()) {
findPath(src, target);
}
return queue.poll();
}
public void findPath(Node src, Node target) {
int x = src.x;
int y = src.y;
Node next = null;
Move nextMove = null;
if(next == null && isValid(x, y-1)) {
next = grid[x][y-1];
nextMove = Move.UP;
}
if(next == null && isValid(x, y+1)) {
next = grid[x][y + 1];
nextMove = Move.DOWN;
}
if(next == null && isValid(x + 1, y)) {
next = grid[x + 1][y];
nextMove = Move.RIGHT;
}
if(next == null && isValid(x - 1, y)) {
next = grid[x - 1][y];
nextMove = Move.LEFT;
}
next.visited = true;
int dist = getDistance(next.type);
for(int i = 0; i < dist; i++) {
queue.add(nextMove);
}
}
public int getDistance(FieldType type) {
int dist = 0;
switch(type) {
case A:
dist = 1;
break;
case B:
dist = 2;
break;
case C:
dist = Integer.MAX_VALUE;
break;
default:
break;
}
return dist;
}
public boolean isValid(int x, int y) {
return x >= 0 && y >= 0 && y < grid.length
&& x < grid[0].length && grid[x][y].visited == false
&& grid[x][y].type != FieldType.C;
}
public Node[][] createGrid(int l, int w) {
return new Node[w][l];
}
}