Пример #1
0
        public void insert(Node node)
        {
            if (size == nodes.Length)
                growArray();

            nodes[size] = node;
            node.positionInHeap = size;
            size++;

            percolateUp(size - 1);
        }
Пример #2
0
        public Path computePath(float startX, float startY, float endX, float endY, out bool pathFound)
        {
            timer.Reset();
            timer.Start();

            Heap open = new Heap();
            //List<Node> closed = new List<Node>();
            bool[,] closed = new bool[width, height];
            int closedSize = 0;
            Node[,] openMap = new Node[width, height];
            Node goal = getNode((int) Math.Round(endX / SCALE), (int) Math.Round(endY / SCALE));
            Node start = getNode((int) Math.Round(startX / SCALE), (int) Math.Round(startY / SCALE));

            if (goal != null && start != null)
            {
                open.insert(start);
                openMap[(int)start.getPosition().X, (int)start.getPosition().Y] = start;
            }
            //else a path can't be found so skip to the end and return default path.

            while (!open.isEmpty())
            {
                //get node with lowest f value from open list (last entry in list)
                Node n = open.removeMin();
                openMap[(int)n.getPosition().X, (int)n.getPosition().Y] = null;

                //closed.Add(n);
                closed[(int)n.getPosition().X, (int)n.getPosition().Y] = true;
                closedSize++;

                if (n.getPosition() == goal.getPosition()) //found a path
                {
                    Node parent = n.getParent();
                    List<Vector3> pathNodes = new List<Vector3>();
                    Vector2 pos = n.getPosition();

                    pathNodes.Add(new Vector3(pos.X * SCALE, pos.Y * SCALE, scaledHeightMap[(int)pos.X, (int)pos.Y]));

                    while (parent != null)
                    {
                        pos = parent.getPosition();
                        pathNodes.Add(new Vector3(pos.X * SCALE, pos.Y * SCALE, scaledHeightMap[(int)pos.X, (int)pos.Y]));
                        parent = parent.getParent();
                    }

                    pathNodes.Add(level.getPositionAt(startX, startY));

                    Console.WriteLine("closed size: " + closedSize);
                    Console.WriteLine(timer.ElapsedMilliseconds + "ms total to run A*");
                    timer.Stop();

                    pathNodes.Reverse();
                    pathNodes.Add(level.getPositionAt(endX, endY));
                    pathFound = true;
                    return new Path(pathNodes);
                }

                //generate successors for n
                List<Node> successors = getSuccessors(n);

                for (int i = 0, m = successors.Count; i < m; i++)
                {
                    Node s = successors[i];

                    //if (!contains(closed, s))
                    if(closed[(int)s.getPosition().X, (int)s.getPosition().Y] == false)
                    {
                        //s.h is estimated distance to goal
                        //s.hVal = Vector2.Distance(s.getPosition(), goal.getPosition());
                        s.hVal = Vector2.DistanceSquared(s.getPosition(), goal.getPosition());
                        //s.g is n.g + cost from n to s
                        s.gVal = n.gVal + s.getDistanceToParent();

                        //If it isn’t on the open list, add it to the open list.
                        //Node oldNode = open.contains(s.getPosition(), out oldNodePos);
                        int sx = (int)s.getPosition().X;
                        int sy = (int)s.getPosition().Y;
                        Node oldNode = openMap[sx, sy];

                        if (oldNode == null)
                        {
                            open.insert(s);
                            openMap[sx, sy] = s;
                        }
                        else
                        {
                            //If it is on the open list already, check to see if this path to that square is better,
                            //using G cost as the measure. A lower G cost means that this is a better path.
                            //If so, change the parent of the square to the current square, and recalculate the G and F scores of the square.
                            //If you are keeping your open list sorted by F score, you may need to resort the list to account for the change.
                            if (s.gVal < oldNode.gVal)
                            {
                                oldNode.setParent(n);
                                oldNode.gVal = s.gVal;
                                open.reorderNode(oldNode.positionInHeap);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("closed size: " + closedSize);
            Console.WriteLine("Took " + timer.ElapsedMilliseconds + "ms to not find a path");
            timer.Stop();

            //couldn't find a path so return a path containing just the start node
            List<Vector3> noPath = new List<Vector3>();
            noPath.Add(level.getPositionAt(startX, startY));
            pathFound = false;
            return new Path(noPath);
        }
Пример #3
0
        /**
         * Determines if it is possible to move between two adjacent nodes.
         *
         * @param a The first node.
         * @param b The second node.
         * @return True if it is possible to move from a to b.
         */
        private bool canMove(Node a, Node b)
        {
            Vector2 posA = a.getPosition();
            Vector2 posB = b.getPosition();

            float diff = Math.Abs(scaledHeightMap[(int)posA.X, (int)posA.Y] - scaledHeightMap[(int)posB.X, (int)posB.Y]);

            return diff <= MAX_MOVE_DIST;
        }
Пример #4
0
        /**
         * Gets a list of successor nodes for a specified node.
         * Each successor node's parent is set to the speified node.
         *
         * @param node The node to get successors for.
         */
        private List<Node> getSuccessors(Node node)
        {
            List<Node> successors = new List<Node>();

            for (int i = 0; i < BORDER_NODES.Length; i++)
            {
                Vector2 pos = node.getPosition() + BORDER_NODES[i];
                Node n = getNode((int)pos.X, (int)pos.Y);

                if (n != null && canMove(node, n))
                {
                    n.setParent(node);
                    successors.Add(n);
                }
            }

            return successors;
        }
Пример #5
0
        /**
         * Sets the parent of this node and calculates the
         * distance to it. If a null parameter is provided
         * then this node has no parent.
         *
         * @param parent The parent node to set or null if the node is to have no parent.
         */
        public void setParent(Node parent)
        {
            this.parent = parent;

            if (parent != null)
                distToParent = Vector2.Distance(pos, parent.pos);
            else
                distToParent = 0.0f;
        }