网格障碍的A *寻路问题

时间:2018-10-15 15:29:03

标签: java search path-finding a-star game-development

说明:

在搜索我的代码很长时间并将其与本网站上询问的其他问题进行比较之后,我仍然不太清楚如何解决此问题。

我目前正忙于为基于2D网格的简单游戏实现A *寻路算法。 该代码基于此伪代码:

// A* (star) Pathfinding

// Initialize both open and closed list
  let the openList equal empty list of nodes
  let the closedList equal empty list of nodes

// Add the start node
    put the startNode on the openList (leave it's f at zero)

// Loop until you find the end
  while the openList is not empty

// Get the current node
    let the currentNode equal the node with the least f value
    remove the currentNode from the openList
    add the currentNode to the closedList

    // Found the goal
    if currentNode is the goal
        Congratz! You've found the end! Backtrack to get path

    // Generate children
    let the children of the currentNode equal the adjacent nodes

    for each child in the children

        // Child is on the closedList
        if child is in the closedList
            continue to beginning of for loop

        // Create the f, g, and h values
        child.g = currentNode.g + distance between child and current
        child.h = distance from child to end
        child.f = child.g + child.h

        // Child is already in openList
        if child.position is in the openList's nodes positions
            if the child.g is higher than the openList node's g
                continue to beginning of for loop

        // Add the child to the openList
        add the child to the openList

所有成本均为1。启发式方法是“曼哈顿距离”。起点是绿色方块,终点是最左边的粉红色方块。

问题:

使用起点(5,3)“绿色”和终点(3,4)“粉红色”的示例,该路径查找对此功能正常,但是只要绿色方块向右移动一个方块,程序进入无限循环。

图片在这里:

Start=(5,3),End=(3,4)

Start=(6,3),End=(3,4)

样本输出:

之前:

java.awt.Point[x=200,y=120]
false

java.awt.Point[x=200,y=120]
java.awt.Point[x=160,y=160]
false

java.awt.Point[x=200,y=120]
java.awt.Point[x=160,y=160]
java.awt.Point[x=120,y=200]
false

java.awt.Point[x=200,y=120]
java.awt.Point[x=160,y=160]
java.awt.Point[x=120,y=200]
java.awt.Point[x=120,y=240]
false

java.awt.Point[x=200,y=120]
java.awt.Point[x=160,y=160]
java.awt.Point[x=120,y=200]
java.awt.Point[x=120,y=240]
java.awt.Point[x=120,y=280]
false

java.awt.Point[x=200,y=120]
java.awt.Point[x=160,y=160]
java.awt.Point[x=120,y=200]
java.awt.Point[x=120,y=240]
java.awt.Point[x=120,y=280]
java.awt.Point[x=120,y=320]
true

之后:

java.awt.Point[x=240,y=120]
false

java.awt.Point[x=240,y=120]
java.awt.Point[x=200,y=160]
false

java.awt.Point[x=240,y=120]
java.awt.Point[x=200,y=160]
java.awt.Point[x=200,y=200]
false

java.awt.Point[x=240,y=120]
java.awt.Point[x=200,y=160]
java.awt.Point[x=200,y=200]
java.awt.Point[x=200,y=240]
false

java.awt.Point[x=240,y=120]
java.awt.Point[x=200,y=160]
java.awt.Point[x=200,y=200]
java.awt.Point[x=200,y=240]
java.awt.Point[x=200,y=280]
false

java.awt.Point[x=240,y=120]
java.awt.Point[x=200,y=160]
java.awt.Point[x=200,y=200]
java.awt.Point[x=200,y=240]
java.awt.Point[x=200,y=280]
java.awt.Point[x=200,y=280]
false

提供的输出是while中每个循环的封闭列表。然后检查当前节点是否为结束节点。

因此由于某种原因,它会不断重复。永远不会结束。

我将在下面包含我的代码,我们将不胜感激。

A *算法。

public Point[] aStar(Map map,Point start, Point end){
        //Returns a list of positions from point start to end.

        //Get map array
        int[][] Mapp = map.getMap();

        //Create astart and end nodes
        Node startNode = new Node(null,start);
        Node endNode = new Node(null,end);


        //Initialize open and closed lists and path list
        ArrayList<Node> open_list = new ArrayList<Node>();
        ArrayList<Node> closed_list = new ArrayList<Node>();
        ArrayList<Node> children = new ArrayList<Node>();
        ArrayList<Point> path = new ArrayList<Point>();

        //Add start node
        open_list.add(startNode);

        //Loop until you find the end
        while(!open_list.isEmpty()){
            //Get this current node
            Node currentNode = open_list.get(0);
            int current_index = 0;
            int counter = 0;

            for(Node node: open_list){
                if(node.getTotal()<currentNode.getTotal()){
                    currentNode = node;
                    current_index = counter;
                    counter++;
                }
            }

            //Pop current node off open list and add to the closed list
            open_list.remove(current_index);
            closed_list.add(currentNode);
            System.out.println();
            for (int i = 0; i <closed_list.size() ; i++) {
                System.out.println(closed_list.get(i).getPosition());

            }

            //Goal
            System.out.println(currentNode.equals(endNode));
            if(currentNode.equals(endNode)){
                Node current = currentNode;
                while(current.getParent() != null){
                    path.add(current.getPosition());
                    current = current.getParent();
                }
                //Reverse path
                Point[] pat = path.toArray(new Point[path.size()]);

                return pat;
            }
            //Array of new positions
            Point[] positions = {new Point(0,-40), new Point(0,40),new Point(-40,0),new Point(40,0),new Point(-40,-40), new Point(-40,40),new Point(40,-40), new Point(40,40)};



            //Generate Children
            childrenloop:
            for(Point newPosition:positions){
                //Get node position
                Point node_position = new Point((int)(currentNode.getPosition().getX()+ newPosition.getX()),(int)(currentNode.getPosition().getY()+ newPosition.getY()));
                //System.out.println(node_position);
                //System.out.println(node_position);
                //Contain in Map
                if(node_position.getX()>(map.getxSize()-40)|| node_position.getX()<0 || node_position.getY()>(map.getySize()-40)|| node_position.getY() <0 ){
                    System.out.println("Out of Bounds");
                    continue;
                }else

                //Check Walkable Terrain
                if(mapping[(int)node_position.getX()/40][(int)node_position.getY()/40] != 0){
                    //System.out.println("Not walkable");
                    continue;
                }else {

                    //Create New Node
                    Node new_Node = new Node(currentNode, node_position);

                    //Add to children
                    children.add(new_Node);
                }

            }

            //Loop through children
            outerloop:
            for(Node child : children){
                //System.out.println(child.getPosition());
                //Check if child is on closed list
                for(Node closed_child : closed_list){
                    if (child.equals(closed_child)){
                        continue outerloop;
                    }
                }

                // Generate the  Total, Distance and Heuristic values
                child.setDistance(currentNode.getDistance()+1);
                int heuristic =(int)Math.round ((Math.pow((child.getPosition().x-endNode.getPosition().x),2))+Math.pow((child.getPosition().y-endNode.getPosition().y),2));
                child.setHeuristic(heuristic);
                child.setTotal();

                //Child already in open list
                for(Node open_node:open_list){
                    if(child.equals(open_node)&& child.getDistance()>open_node.getDistance()){
                        continue outerloop;
                    }
                }

                //Add child to open list
                open_list.add(child);
            }



        }

        return null;

    }

节点:

public class Node {
    //Node class for A*
    Node parent;
    Point position;

    int distance,heuristic,total;

    public Node(Node parent, Point position){
        this.parent = parent;
        this.position  = position;

        this.distance = 0;
        this.heuristic = 0;
        this.total = 0;
    }

    public boolean equals(Node other){
        return this.position.equals(other.position);
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public Point getPosition() {
        return position;
    }

    public void setPosition(Point position) {
        this.position = position;
    }

    public int getDistance() {
        return distance;
    }

    public void setDistance(int distance) {
        this.distance = distance;
    }

    public int getHeuristic() {
        return heuristic;
    }

    public void setHeuristic(int heuristic) {
        this.heuristic = heuristic;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal() {
        this.total = heuristic+distance;
    }

    public String toString(){
        return position.toString();
    }
}

地图:

public class Map {
    final BizarreBazaar game;
    ExploreScreen screen;
    int level;
    int xSize;
    int ySize;
    int[][] map;
    ArrayList<Entity> entities = new ArrayList<Entity>();
    public Map(int level,final BizarreBazaar game,ExploreScreen screen) {
        this.screen = screen;
        this.game = game;
        this.level=level;
        setMap();
    }

    public void setMap(){
        switch(level){
            case 1:
                xSize = 15;
                ySize = 15;
                map = new int[][]{
                                {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,1,1,1,1,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,1,1,1,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                                {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                        };
                entities.add(new Player(game,screen, 5*40, 3*40, 40, 40, 40.0f, new Texture("player.png"),"player"));
                entities.add(new Entity(game,screen, 120, 320, 40, 40, 40.0f, new Texture("enemy.png"),""));
                entities.add(new Entity(game,screen, 400, 400, 40, 40, 40.0f, new Texture("enemy.png"),""));
                entities.add(new Entity(game,screen, 360, 120, 40, 40, 40.0f, new Texture("enemy.png"),""));
                break;
 public ArrayList<Entity> getEntities(){
        return new ArrayList<Entity>(entities);
    }

    public int[][] getMap(){
        return map;
    }

    public int getxSize() {
        return xSize*40;
    }

    public int getySize() {
        return ySize*40;
    }
}

0 个答案:

没有答案