예제 #1
0
파일: Point.cs 프로젝트: dennex/PathFinder
 // this is to compare two points with double precision coordinates
 public static bool Identical(Node A, Node B)
 {
     if (IdenticalCoord(A.x,B.x) && IdenticalCoord(A.y,B.y)) // x and y very close, then point is identical
         return true;
     else
         return false;
 }
예제 #2
0
        private int Start(Node startNode)
        {
            int pathsFound = 0;
            Stack<Node> stack = new Stack<Node>();
            Stack<Node> pathTraversed = new Stack<Node>();

            Node currNode = startNode;

            while (currNode != null)
            {
                if (currNode.IsVisited)
                {
                    currNode = stack.Pop();
                    continue;
                }

                pathTraversed.Push(currNode);
                stack.Push(currNode);

                if (currNode.IsEndNode)
                {
                    if (pathTraversed.Count == Maze.Length - numberOfPits)
                    {
                        pathsFound++;
                        pathTraversed.Pop();
                        var fs = new StreamWriter("d:\\pf.txt", true);
                        fs.WriteLine(string.Join("->", pathTraversed.Reverse()));
                        fs.Close();
                        currNode = stack.Pop();
                        currNode.IsVisited = false;
                        currNode = stack.Pop();
                        currNode.IsVisited = false;
                        while (null == (currNode = currNode.getNextBranch()))
                        {
                            currNode = stack.Pop();
                            currNode.IsVisited = false;
                        }
                        continue;
                    }
                }

                currNode.IsVisited = true;

                var nextBranchOfThisNode = currNode = currNode.getNextBranch();

                if (nextBranchOfThisNode == null)
                {
                    currNode.IsVisited = false;
                    currNode = stack.Pop();
                }
            }

            return pathsFound;
        }
예제 #3
0
        /// <summary>
        /// Creates the final path after it is found
        /// </summary>
        /// <param name="startTile"></param>
        /// <param name="endTile"></param>
        public override Vector3[] CreatePath(Node startTile, Node endTile, bool simplified)
        {
            List<Node> path = new List<Node>();
            Node currentTile = endTile;

            //Constructs the path by starting at the target position
            //and getting the parent of each tile until it gets to the start
            while (currentTile != startTile)
            {
                path.Add(currentTile);
                currentTile = currentTile.myParent;
            }
            path.Add(startTile);
            Vector3[] simplifiedPath = Simplify(path, simplified, distort);
            Array.Reverse(simplifiedPath);
            return simplifiedPath;
        }
예제 #4
0
        public NonRecursivePathfinder AddPoints(int[,] matrix)
        {
            Maze = new Node[matrix.GetLength(0), matrix.GetLength(1)];

            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (var j = 0; j < matrix.GetLength(1); j++)
                {
                    Node node = Maze[i, j];

                    if (node == null)
                    {
                        node = new Node(matrix[i, j]);
                        Maze[i, j] = node;
                    }
                    if (!(i - 1 < 0))
                        Maze[i - 1, j].DownNode = node;

                    if (!(i + 1 > matrix.GetLength(0) - 1))
                    {
                        var downNode = Maze[i + 1, j];
                        if (downNode == null)
                            Maze[i + 1, j] = new Node(matrix[i + 1, j]);
                        Maze[i + 1, j].UpNode = node;
                    }

                    if (!(j - 1 < 0))
                        Maze[i, j - 1].RightNode = node;

                    if (!(j + 1 > matrix.GetLength(1) - 1))
                    {
                        var leftNode = Maze[i, j + 1];
                        if (leftNode == null)
                            Maze[i, j + 1] = new Node(matrix[i, j + 1]);
                        Maze[i, j + 1].LeftNode = node;
                    }

                    node.Name = ((char)(65 + i)).ToString() + j.ToString();
                    if (node.IsPit)
                        numberOfPits++;
                }
            }

            return this;
        }
예제 #5
0
        /// <summary>
        /// Gets the adjacent tiles
        /// for a given tile
        /// </summary>
        /// <param name="_t"></param>
        /// <returns></returns>
        public override List<Node> GetAdjacents(Node _t)
        {
            List<Node> adjacents = new List<Node>();
            for(int x = -1; x <= 1; x++)
            {
                for(int y = -1; y <= 1; y++)
                {
                    if (x == 0 && y == 0) continue;

                    int checkX = _t.gridX + x;
                    int checkY = _t.gridY + y;

                    if(checkX >= 0 && checkX < sizeX && checkY >= 0 && checkY < sizeY)
                    {
                        adjacents.Add(grid[checkX, checkY]);
                    }
                }
            }
            return adjacents;
        }
예제 #6
0
파일: Point.cs 프로젝트: dennex/PathFinder
 public Segment(Node node1, Node node2)
 {
     this.point1 = new Point(node1.x, node1.y);
     this.point2 = new Point(node2.x, node2.y);
 }
예제 #7
0
파일: Point.cs 프로젝트: dennex/PathFinder
 public Segment(Node node1)
 {
     if (node1.direction == Direction.Horizontal)
     {// horizontal node
         point1 = new Point(node1.x - 0.5, node1.y);
         point2 = new Point(node1.x + 0.5, node1.y);
     }
     else
     {// horizontal node
         point1 = new Point(node1.x, node1.y-0.5);
         point2 = new Point(node1.x, node1.y+0.5);
     }
 }
 /// <summary>
 /// Creates the final path after it is found
 /// </summary>
 /// <param name="startTile"></param>
 /// <param name="endTile"></param>
 public abstract Vector3[] CreatePath(Node startTile, Node endTile, bool simplified);
예제 #9
0
        /// <summary>
        /// This function looks through the intersections of a square between weight nodes. It searches clockwise from the angle of entrance from the last segment
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="startNode"></param>
        /// <param name="startAngle"></param>
        /// <param name="foundAngle"></param>
        /// <returns></returns>
        public static Node SearchSegmentEnd(List<Node> nodes, Node startNode, int startAngle, out int foundAngle)
        {
            // find the end of the segment which starts at "startNode" and had angle coming in "startAngle"
            bool found = false;
            int foundIndex = -1;
            foundAngle = -1;
            int i = 0;

            // by making this loop run by the number of times there are angles, we permit dead-ends for the segment to go back on itself
            for (i = (GetAngleIndex(startAngle) + Angles.Count() - 1) % Angles.Count(); i <= Angles.Count() && found == false; i = (i + Angles.Count() - 1) % Angles.Count())
            {
                int x = (int)startNode.x;
                int ceilX = (int)Math.Ceiling(startNode.x);
                int floorX = (int)Math.Floor(startNode.x);
                int y = (int)startNode.y;
                int ceilY = (int)Math.Ceiling(startNode.y);
                int floorY = (int)Math.Floor(startNode.y);

                switch (Angles[i])
                {
                    case 0:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x + 1, -1, floorY, ceilY, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 0;
                            }

                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = false;
                        }
                        break;
                    case 45:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x, x + 1, floorY, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 45;
                            }
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, ceilX, -1, y - 1, y, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 45;
                            }
                        }
                        break;
                    case 90:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = false;
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, floorX, ceilX, y - 1, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 90;
                            }
                        }
                        break;
                    case 135:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x - 1, x, floorY, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 135;
                            }
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, floorX, -1, y - 1, y, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 135;
                            }
                        }
                        break;
                    case 180:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x - 1, -1, floorY, ceilY, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 180;
                            }
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = false;
                        }
                        break;
                    case 225:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x - 1, x, ceilY, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 225;
                            }
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, floorX, -1, y, y + 1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 225;
                            }
                        }
                        break;
                    case 270:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = false;
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, floorX, ceilX, y + 1, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 270;
                            }
                        }
                        break;
                    case 315:
                        if (startNode.direction == Direction.Horizontal)
                        {
                            found = SearchNodes(nodes, x, x + 1, ceilY, -1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 315;
                            }
                        }
                        else
                        {//  when vertical we don't have 0 degree search case
                            found = SearchNodes(nodes, ceilX, -1, y, y + 1, out foundIndex);
                            if ( found == true)
                            {
                                foundAngle = 315;
                            }
                        }
                        break;
                }
            }

            if (found == true)
            {
                return nodes.ElementAt(foundIndex);
            }
            else
            {
                return null;
            }
        }
예제 #10
0
        public Point[] findPath(Point start, Point end, ref int time)
        {
            List<Point> p = new List<Point>(); //конечный список

            current = new Node(start, 0, 0, 0);
            current.H = calcH(start, end);
            current.F = current.H;
            openList.Add(current);
            existsArray[current.P.X, current.P.Y] = 1;

            bool ex = false;
            bool can = true;
            while (!ex)
            {
                int i = findMinF(openList);
                current = openList[i];
                openList.RemoveAt(i);
                closeList.Add(current);
                existsArray[current.P.X, current.P.Y] = 2;

                //проверка соседних клеток
                Point nb = current.P;
                nbPoint(new Point(nb.X + 1, nb.Y), current, end, x, y);
                nbPoint(new Point(nb.X, nb.Y - 1), current, end, x, y);
                nbPoint(new Point(nb.X - 1, nb.Y), current, end, x, y);
                nbPoint(new Point(nb.X, nb.Y + 1), current, end, x, y);

                if (openList.Count == 0) //открытый списко пустой - путь невозможен
                {
                    ex = true;
                    can = false;
                }
                if (existsArray[end.X, end.Y] == 1) //дошли до финала
                    ex = true;
            }

            //составление искомого пути
            if (can)
            {
                /*
                List<Node> list = new List<Node>();
                foreach (Node n in openList)
                    list.Add(n);
                foreach (Node n in closeList)
                    list.Add(n);

                p.Add(end);
                Point pp = end;
                int i = 0;

                while (pp != start)
                {
                    i = inList(pp, list);
                    if (i < 0)
                        break;
                    pp = list[i].Parent;
                    p.Add(pp);
                    list.RemoveAt(i);
                }*/
                p.Add(end);
                Point pp = end;
                int i = 0;

                while (pp != start)
                {
                    if (existsArray[pp.X, pp.Y] == 1)
                    {
                        i = inList(pp, openList);
                        if (i < 0)
                            break;

                        if (pp == end)
                            time = openList[i].G;

                        pp = openList[i].Parent;
                    }
                    else if (existsArray[pp.X, pp.Y] == 2)
                    {
                        i = inList(pp, closeList);
                        if (i < 0)
                            break;
                        pp = closeList[i].Parent;
                    }
                    p.Add(pp);
                }
            }

            Point[] ret = new Point[p.Count];
            for (int i = 0; i < p.Count; i++)
                ret[i] = p[p.Count - i - 1];

            clear();

            return ret;
        }
예제 #11
0
        /// <summary>
        /// Gets the distance between two tiles
        /// Uses Diagonal Distance for calculating 
        /// the distance
        /// </summary>
        /// <param name="_currentTile"></param>
        /// <param name="_endTile"></param>
        /// <returns></returns>
        public int GetDistance(Node _currentTile, Node _endTile, DistanceHeuristic _distanceType)
        {
            int dx = Mathf.Abs(_currentTile.gridX - _endTile.gridX);
            int dy = Mathf.Abs(_currentTile.gridY - _endTile.gridY);

            ///////DEFUALT////////
            //Square Grid that allows 8 directions of movement
            if (_distanceType == DistanceHeuristic.DIAGONAL)
            {
                //3/2 are used for calculating the diagonal distance
                if (dx > dy)
                    return 14 * dy + 10 * (dx - dy);
                return 14 * dx + 10 * (dy - dx);
            }

            else

            //Square Grid that allows 4 directions of movement
            //UP, DOWN, LEFT, RIGHT
            if (_distanceType == DistanceHeuristic.MANHATTAN)
            {
                return 14 * (dx + dy);
            }

            else

            //Square grid that allows any direction of movement
            //NOT restricted to a grid, **SLOWER
            if (_distanceType == DistanceHeuristic.EUCLIDEAN)
            {
                return (int)(14 * Mathf.Sqrt(dx * dx + dy * dy));
            }

            return 0;
        }
예제 #12
0
        private int calcG(Node node)
        {
            int g = current.G;
            if (current.P.X == node.P.X && current.P.Y != node.P.Y)
                g += 1;
            else if (current.P.X != node.P.X && current.P.Y == node.P.Y)
                g += 1;

            if (tissue[node.P.X, node.P.Y].AreaType == VG.Map.AreaEnum.LowDensity)
                g += 1;
            else if (tissue[node.P.X, node.P.Y].AreaType == VG.Map.AreaEnum.MediumDensity)
                g += 2;
            else if (tissue[node.P.X, node.P.Y].AreaType == VG.Map.AreaEnum.HighDensity)
                g += 3;

            VG.Map.BloodStream bs = tissue.IsInStream(node.P.X, node.P.Y);
            if (bs != null)
            {
                int dy = node.P.Y - current.P.Y;
                int dx = node.P.X - current.P.X;

                #region Direction
                bool plus = false;
                if (bs.Direction == VG.Map.BloodStreamDirection.NorthSouth)
                {
                    if (dy >= 0)
                        plus = false;
                    else
                        plus = true;
                }
                else if (bs.Direction == VG.Map.BloodStreamDirection.SouthNorth)
                {
                    if (dy <= 0)
                        plus = false;
                    else
                        plus = true;
                }
                else if (bs.Direction == VG.Map.BloodStreamDirection.EstWest)
                {
                    if (dx <= 0)
                        plus = false;
                    else
                        plus = true;
                }
                else if (bs.Direction == VG.Map.BloodStreamDirection.WestEst)
                {
                    if (dx >= 0)
                        plus = false;
                    else
                        plus = true;
                }

                if (plus)
                    g += 2;
                else
                    g -= 2;

                #endregion
            }

            return g;
        }
예제 #13
0
        /// <summary>
        /// Traverses a node.
        /// </summary>
        /// <param name="node"></param>
        private void Traverse(Node node)
        {
            if (node == null)
                return;

            if (node.IsEntranceNode || node.IsPit || node.IsVisited)
                return;

            if (node.IsExitNode)
            {
                pathTraversed.Push(node.Name);
                if (pathTraversed.Count == Maze.Length - numberOfPits)
                {
                    var msg = "Path " + pathCount++ + " : " + string.Join("->", pathTraversed.Reverse());
                    Console.WriteLine(msg);
                }
                pathTraversed.Pop();
                return;
            }

            pathTraversed.Push(node.Name);
            node.IsVisited = true;

            Traverse(node.RightNode);   //
            Traverse(node.DownNode);    // Move to Next Node
            Traverse(node.LeftNode);    //
            Traverse(node.UpNode);      //

            if (node.Name != pathTraversed.Peek())
                throw new Exception("Error in Logic.");

            node.IsVisited = false;
            pathTraversed.Pop();
        }
예제 #14
0
 public int CompareTo(Node _t)
 {
     int value = fScore.CompareTo(_t.fScore);
     if (value == 0) value = hScore.CompareTo(_t.hScore);
     return -value;
 }
예제 #15
0
파일: Map.cs 프로젝트: MightyKingM/Files
 public Map()
 {
     root = new Node();
 }
예제 #16
0
파일: Map.cs 프로젝트: MightyKingM/Files
 public Map(Node root)
 {
     this.root = root;
 }
예제 #17
0
        protected override void CreateGraph()
        {
            grid = new Node[sizeX, sizeY];
            Vector3 bottomLeftCorner = transform.position - Vector3.right * GraphSize.x / 2 - Vector3.forward * GraphSize.z / 2;

            for(int x=0; x < sizeX; x++ )
            {
                for (int y = 0; y < sizeY; y++)
                {
                    Vector3 worldPoint = bottomLeftCorner + Vector3.right * (x * tileDiameter + tileSizes) + Vector3.forward * (y * tileDiameter + tileSizes);
                    bool walkable = !(Physics.CheckSphere(worldPoint,tileSizes,myLayer));
                    grid[x, y] = new Node(walkable, worldPoint, x, y);
                    //myTiles.Add(grid[x, y]);
                }
            }
        }
예제 #18
0
        private void nbPoint(Point nb, Node current, Point end, int X, int Y)
        {
            if (nb.X >= X || nb.X < 0)
                return;
            if (nb.Y >= Y || nb.Y < 0)
                return;
               // if (ifExistsInList(nb, closeList))
            if (existsArray[nb.X, nb.Y] == 2)
                return;
            if (!tissue.IsInMap(nb.X, nb.Y))
                return;
            if( tissue[nb.X,nb.Y].AreaType == VG.Map.AreaEnum.Bone )
                return;

            //if (!ifExistsInList(nb, openList))
            if(existsArray[nb.X,nb.Y] !=1 )
            {
                Node n = new Node(nb, 0, 0, 0);
                n.H = calcH(nb, end);
                n.G = calcG(n);

                n.F = n.G + n.H;
                n.Parent = current.P;
                openList.Add(n);
                existsArray[n.P.X, n.P.Y] = 1;
            }
            else
            {
                Node n = openList[inList(nb, openList)];
                if (n.G < calcG(n))
                {
                    n.Parent = current.P;
                    n.G = calcG(n);
                    n.F = n.G + n.H;

                    int j = inList(nb, openList);
                    existsArray[openList[j].P.X, openList[j].P.Y] = 0;
                    openList.RemoveAt(j);
                    openList.Add(n);
                    existsArray[n.P.X, n.P.Y] = 1;
                }
            }
        }
예제 #19
0
        public Point[] findPath(Point start, Point end)
        {
            List<Point> p = new List<Point>();
            current = new Node(start, 0, 0, 0);
            current.H = calcH(start, end);
            current.F = current.H;
            openList.Add(current);
            existsArray[current.P.X, current.P.Y] = 1;

            bool ex = false;
            bool can = true;
            while (!ex)
            {
                int i = findMinF(openList);
                current = openList[i];
                openList.RemoveAt(i);
                closeList.Add(current);
                existsArray[current.P.X, current.P.Y] = 2;

                Point nb = current.P;
                nbPoint(new Point(nb.X + 1, nb.Y), current, end, x, y);
                nbPoint(new Point(nb.X, nb.Y - 1), current, end, x, y);
                nbPoint(new Point(nb.X - 1, nb.Y), current, end, x, y);
                nbPoint(new Point(nb.X, nb.Y + 1), current, end, x, y);

                if (openList.Count == 0)
                {
                    ex = true;
                    can = false;
                }
                //if (ifExistsInList(end, openList))
                if (existsArray[end.X, end.Y] == 1)
                    ex = true;
            }

            if (can)
            {
                List<Node> list = new List<Node>();
                foreach (Node n in openList)
                    list.Add(n);
                foreach (Node n in closeList)
                    list.Add(n);

                p.Add(end);
                Point pp = end;
                int i = 0;

                while (pp != start)
                {
                    i = inList(pp, list);
                    if (i < 0)
                        break;
                    pp = list[i].Parent;
                    p.Add(pp);
                    list.RemoveAt(i);
                }
            }

            Point[] ret = new Point[p.Count];
            for (int i = 0; i < p.Count; i++)
                ret[i] = p[p.Count - i - 1];

            return ret;
        }
예제 #20
0
        //функция обрабатывющая "соседнюю" клетку
        private void nbPoint(Point nb, Node current, Point end, int X, int Y)
        {
            //различные проверки клетки - границы массива,закрытый список итд.
            if (nb.X >= X || nb.X < 0)
                return;
            if (nb.Y >= Y || nb.Y < 0)
                return;
            if (existsArray[nb.X, nb.Y] == 2)
                return;
            if (!tissue.IsInMap(nb.X, nb.Y))
                return;
            if( tissue[nb.X,nb.Y].AreaType == VG.Map.AreaEnum.Bone )
                return;

            //если нет в открытом списке - добавляем
            if(existsArray[nb.X,nb.Y] !=1 )
            {
                Node n = new Node(nb, 0, 0, 0);
                n.H = calcH(nb, end);
                n.G = calcG(n);

                n.F = n.G + n.H;
                n.Parent = current.P;
                openList.Add(n);
                existsArray[n.P.X, n.P.Y] = 1;
            }
            else //если есть - страдаем некоторой фигней =)
            {
                Node n = openList[inList(nb, openList)];
                if (n.G > calcG(n))
                {
                    n.Parent = current.P;
                    n.G = calcG(n);
                    n.F = n.G + n.H;

                    int j = inList(nb, openList);
                    existsArray[openList[j].P.X, openList[j].P.Y] = 0;
                    openList.RemoveAt(j);
                    openList.Add(n);
                    existsArray[n.P.X, n.P.Y] = 1;
                }
            }
        }