简体   繁体   English

为什么在这个寻路算法中路径是反向的?

[英]Why is the path reversed in this path-finding algorithm?

I'm creating a 2d top down game where the enemy AI is constantly following the player and avoiding obstacles.我正在创建一个 2d 自上而下的游戏,其中敌人的 AI 不断跟随玩家并避开障碍物。 I did some research about path-finding algorithms and I decided to implement the breadth first search, but for some reason, the xy coordinates of the path are reversed, even though the grid is correct.我做了一些关于寻路算法的研究,我决定实现广度优先搜索,但由于某种原因,即使网格是正确的,路径的 xy 坐标也被颠倒了。
Code:代码:


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BFSTest {
    // 1 = normal node
    // 0 = obstacle
    // S = start
    // D = destination
    private static char[][] nodes = {
            {'S', '1', '1', '1'}, 
            {'0', '0', '0', '1'}, 
            {'0', '0', '0', '1'}, 
            {'1', '1', '1', 'D'}
        };
  
    public static void main(String[] args) {
        shortestPath();
    }

    public static List<Node> shortestPath() {
        // key node, value parent
        Map<Node, Node> parents = new HashMap<Node, Node>();
        Node start = null;
        Node end = null;

        // find the start node
        for (int row = 0; row < nodes.length; row++) {
            for (int column = 0; column < nodes[row].length; column++) {
                if (nodes[row][column] == 'S') {
                    start = new Node(row, column, nodes[row][column]);
                    break;
                }
            }
        }

        if (start == null) {
            throw new RuntimeException("can't find start node");
        }

        // traverse every node using breadth first search until reaching the destination
        List<Node> temp = new ArrayList<Node>();
        temp.add(start);
        parents.put(start, null);

        boolean reachDestination = false;
        while (temp.size() > 0 && !reachDestination) {
            Node currentNode = temp.remove(0);
            List<Node> children = getChildren(currentNode);
            for (Node child : children) {
                // Node can only be visited once
                if (!parents.containsKey(child)) {
                    parents.put(child, currentNode);
                    char value = child.getValue();
                    if (value == '1') {
                        temp.add(child);
                    } else if (value == 'D') {
                        temp.add(child);
                        reachDestination = true;
                        end = child;
                        break;
                    }
                }
            }
        }
        if (end == null) {
            throw new RuntimeException("can't find end node");
        }
        // get the shortest path
        Node node = end;
        List<Node> path = new ArrayList<Node>();
        while (node != null) {
            path.add(0, node);
            node = parents.get(node);
        }
        printPath(path);
        return path;
    }

    private static List<Node> getChildren(Node parent) {
        List<Node> children = new ArrayList<Node>();
        int x = parent.getX();
        int y = parent.getY();
        if (x - 1 >= 0) {
            Node child = new Node(x - 1, y, nodes[x - 1][y]);
            children.add(child);
        }
        if (y - 1 >= 0) {
            Node child = new Node(x, y - 1, nodes[x][y - 1]);
            children.add(child);
        }
        if (x + 1 < nodes.length) {
            Node child = new Node(x + 1, y, nodes[x + 1][y]);
            children.add(child);
        }
        if (y + 1 < nodes[0].length) {
            Node child = new Node(x, y + 1, nodes[x][y + 1]);
            children.add(child);
        }
        return children;
    }

    private static void printPath(List<Node> path) {
        for (int row = 0; row < nodes.length; row++) {
            for (int column = 0; column < nodes[row].length; column++) {
                String value = nodes[row][column] + "";

                // mark path with X
                for (int i = 1; i < path.size() - 1; i++) {
                    Node node = path.get(i);
                    if (node.getX() == row && node.getY() == column) {
                        value = "X";
                        break;
                    }
                }
                if (column == nodes[row].length - 1) {
                    System.out.println(value);
                } else {
                    System.out.print(value + "  ");
                }
            }
        }
        System.out.println("Path: " + path);
    }
}

class Node {
    
    private int x;
    private int y;
    private char value;

    public Node(int x, int y, char value) {
        this.x = x;
        this.y = y;
        this.value = value;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public char getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "(x: " + x + " y: " + y + ")";
    }

    @Override
    public int hashCode() {
        return x * y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        if (this.getClass() != o.getClass()) return false;
        Node node = (Node) o;
        return x == node.x && y == node.y;
    }
    /* Output:
     * S  X  X  X
     * 0  0  0  X
     * 0  0  0  X
     * 1  1  1  D
     * Path: [(x: 0 y: 0), (x: 0 y: 1), (x: 0 y: 2), (x: 0 y: 3), (x: 1 y: 3), (x: 2 y: 3), (x: 3 y: 3)]
     */
}

Thanks!谢谢!

Think about this for a moment.对此稍加思考。 Remember that your first array index is row , and the second is column .请记住,您的第一个数组索引是row ,第二个是column Now, in terms of conventional x and y :现在,就传统的xy

  • the y index always refers to the row (because you count rows vertically); y索引总是指(因为你垂直计算行数);
  • the x index always refers to the column (because you count columns horizontally). x索引总是指(因为您水平计算列)。

So, the correct way to index your grid is nodes[y][x]因此,索引网格的正确方法是nodes[y][x]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM