我使用 A* 作为我的寻路算法。玩家每回合最多只能移动 4 步。
我希望能够获得路径的 4 个最佳移动,而不是完整路径(每轮都计算 A* 搜索)。
有没有办法只用 4 个最佳移动(最低成本和最短路线)来创建一条路径,而不是每次都找到完整的路径?
我确实看了看,也许你可以在 A* 搜索之前检查机器人位置的 X 和 Y,如果 A* 搜索产生一个节点 > 那么它可以去的瓷砖数量就可以了。但是给出了一个奇怪的路径,因为它在瓷砖数量 > 时停止并且不会继续检查其他瓷砖以查看它是否最好,并且在机器人达到目标时也不会停止。
用if(current.position.equals(goal)
替换if(current.position.getX() > bot.getX() + 6|| current.position.getY() > bot.getY() + 6)
提供完整目标路径的当前代码:
private Comparator<Node> nodeSorter = new Comparator<Node>() {
@Override
public int compare(Node n0, Node n1) {
if(n1.fCost < n0.fCost) return 1;
if(n1.fCost > n0.fCost) return -1;
return 0;
}
};
public List<Node> findPath(Player bot, Position goal){
openList = new ArrayList<Node>();
closedList = new ArrayList<Node>();
List<Node> neighbors = new ArrayList<Node>();
Node current = new Node(bot, bot.getFace(), NONE, null, 0, bot.distance(goal));
openList.add(current);
while(openList.size() > 0) {
Collections.sort(openList, nodeSorter);
current = openList.get(0);
if(current.position.equals(goal)) {
List<Node> path = new ArrayList<Node>();
while(current.parent != null) {
path.add(current);
current = current.parent;
}
openList.clear();
closedList.clear();
return path;
}
openList.remove(current);
closedList.add(current);
int x = current.position.getX();
int y = current.position.getY();
switch (current.face) {
case NORTH:
neighbors.add(new Node(new Position(x, y), NORTH, NONE,current,0,0));
neighbors.add(new Node(new Position(x, y+1), NORTH, FORWARD,current,0,0));
neighbors.add(new Node(new Position(x-1, y+1), WEST, LEFT,current,0,0));
neighbors.add(new Node(new Position(x+1, y+1), EAST, RIGHT,current,0,0));
break;
case EAST:
neighbors.add(new Node(new Position(x, y), EAST, NONE,current,0,0));
neighbors.add(new Node(new Position(x+1, y), EAST, FORWARD,current,0,0));
neighbors.add(new Node(new Position(x+1, y+1), NORTH, LEFT,current,0,0));
neighbors.add(new Node(new Position(x+1, y-1), SOUTH, RIGHT,current,0,0));
break;
case SOUTH:
neighbors.add(new Node(new Position(x, y), SOUTH, NONE,current,0,0));
neighbors.add(new Node(new Position(x, y-1), SOUTH, FORWARD,current,0,0));
neighbors.add(new Node(new Position(x-1, y-1), WEST, RIGHT,current,0,0));
neighbors.add(new Node(new Position(x+1, y-1), EAST, LEFT,current,0,0));
break;
case WEST:
neighbors.add(new Node(new Position(x, y), WEST, NONE,current,0,0));
neighbors.add(new Node(new Position(x-1, y), WEST, FORWARD,current,0,0));
neighbors.add(new Node(new Position(x-1, y+1), NORTH, RIGHT,current,0,0));
neighbors.add(new Node(new Position(x-1, y-1), SOUTH, LEFT,current,0,0));
break;
}
for(Node neighborNode : neighbors) {
if(neighborNode.position.getX() < 0 || neighborNode.position.getY() < 0 ||
neighborNode.position.getX() > MAP_WIDTH || neighborNode.position.getY() > MAP_HEIGHT )continue;
double costTo = current.position.distance(neighborNode.position);
double gCost = current.gCost + costTo;
double hCost = getheuristicDistance(neighborNode.position,goal);
Node node = new Node(neighborNode.position, neighborNode.face,neighborNode.move, current, gCost, hCost);
if(positionInList(closedList, neighborNode.position) && gCost >= node.gCost) continue;
if(!positionInList(openList, neighborNode.position) || gCost < node.gCost)openList.add(node);
}
}
closedList.clear();
return null;
}