Пример #1
0
 void AddDoors(RegionPath source, RegionPath destination)
 {
     for (int i = 0; i < source.Indexes.Length; i++)
     {
         Location location =
             new Location(destination.Region, destination.Indexes[i]);
         source.Region.AddDoor(location, source.Indexes[i]);
     }
 }
Пример #2
0
        // Поиск пути в потоке GUI
        private void btFind_Click(object sender, EventArgs e)
        {
            JuniorPathFinderCore.Heuristics.IHeuristic2D heuristic = new JuniorPathFinderCore.Heuristics.Manhatan2D();
            RegionPath path = pfGrid.Map.GetPath(pfGrid.StartPosition, pfGrid.EndPosition, comparer, heuristic, walcable, weights, priority);

            if (path == null)
            {
                MessageBox.Show("Путь не найден");
                return;
            }
            pfGrid.Path = path;
        }
Пример #3
0
    void CalculateRegionDistances()
    {
        regionDistances = new Dictionary <int, float>();

        // Custom pairing algorithm for int keys of a bounded set of natural numbers.
        // key = (lowestOfPair * upperBound + 1) + highestOfPair

        regionCount = regions.Count;
        upperBound  = regions[regionCount - 1].id;

        for (int startRegionID = 0; startRegionID < regionCount; startRegionID++)
        {
            // The index of goalRegion always starts above startRegion to prevent redundant calculations.
            for (int goalRegionID = startRegionID + 1; goalRegionID < regionCount; goalRegionID++)
            {
                float distance = 0f;

                RegionPath path = pathfinder.FindRegionPath(regions[startRegionID], regions[goalRegionID], false);

                if (path == null)
                {
                    distance = Mathf.Infinity;
                }
                else
                {
                    for (int i = 0; i < path.points.Count - 1; i++)
                    {
                        distance += Vector3.Distance(path.points[i].position, path.points[i + 1].position);
                    }
                }

                int key = startRegionID * (upperBound + 1) + goalRegionID;
                regionDistances.Add(key, distance);
            }
        }
    }
    public RegionPath FindRegionPath(Region start, Region goal, bool isJumping)
    {
        regionManager.ResetAllSearchData();

        /// <summary> Unsearched regions waiting in the priority queue. </summary>
        PriorityQueue <Region> regionOpenList = new PriorityQueue <Region>();
        /// <summary> Fully searched regions. </summary>
        List <Region> closedList = new List <Region>();

        start.gCost = 0;
        start.hCost = Mathf.Abs(
            Vector3.Distance(start.centerPosition, goal.centerPosition)
            );
        start.fCost = start.hCost;

        regionOpenList.Enqueue(start, start.fCost);

        start.SearchStatus = SearchStatus.OpenList;

        while (!regionOpenList.IsEmpty())
        {
            Region bestRegion = regionOpenList.Dequeue();
            if (bestRegion == goal)
            {
                //Construct Path
                RegionPath regionPath   = new RegionPath();
                Region     regionOnPath = bestRegion;
                while (regionOnPath != start)
                {
                    regionPath.AddPoint(new RegionPathPoint(RegionPathPointType.Region, regionOnPath, null, regionOnPath.centerPosition));
                    regionOnPath.SearchStatus = SearchStatus.OnPath;
                    regionPath.AddPoint(new RegionPathPoint(RegionPathPointType.Portal, null, regionOnPath.portalOfParent, regionOnPath.portalOfParent.position));
                    regionOnPath = regionOnPath.parent;
                }
                regionPath.AddPoint(new RegionPathPoint(RegionPathPointType.Region, start, null, start.centerPosition));
                regionOnPath.SearchStatus = SearchStatus.OnPath;

                return(regionPath);
            }
            else
            {
                Region neighbor;

                for (int i = 0; i < bestRegion.portals.Count; i++)
                {
                    neighbor = bestRegion.portals[i].OtherRegion(bestRegion);
                    if (neighbor.SearchStatus == SearchStatus.None)
                    {
                        if (bestRegion.portals[i].EdgeType == EdgeType.Elevated)
                        {
                            if (!isJumping) // If jumping is not allowed, ignore this region and start analyzing the next.
                            {
                                continue;
                            }
                            else // Otherwise, simply calcualte costs as normal.
                            {
                                neighbor.gCost = bestRegion.gCost + bestRegion.portals[i].Cost;
                            }
                        }
                        else
                        {
                            neighbor.gCost = bestRegion.gCost + bestRegion.portals[i].Cost;
                        }

                        neighbor.hCost          = Mathf.Abs(Vector3.Distance(neighbor.centerPosition, goal.centerPosition)) * heuristicWeight;
                        neighbor.fCost          = neighbor.gCost + neighbor.hCost;
                        neighbor.parent         = bestRegion;
                        neighbor.portalOfParent = bestRegion.portals[i];

                        regionOpenList.Enqueue(neighbor, neighbor.fCost);

                        neighbor.SearchStatus = SearchStatus.OpenList;
                    }
                    else if (neighbor.SearchStatus == SearchStatus.OpenList)
                    {
                        float gCost = bestRegion.gCost + bestRegion.portals[i].Cost;
                        float fCost = gCost + neighbor.hCost;

                        if (fCost < neighbor.fCost)
                        {
                            neighbor.gCost          = gCost;
                            neighbor.fCost          = fCost;
                            neighbor.parent         = bestRegion;
                            neighbor.portalOfParent = bestRegion.portals[i];
                        }
                    }
                    else if (neighbor.SearchStatus == SearchStatus.ClosedList)
                    {
                        continue;
                    }
                }
                closedList.Add(bestRegion);
                bestRegion.SearchStatus = SearchStatus.ClosedList;
            }
        }

        return(null);
    }