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]); } }
// Поиск пути в потоке 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; }
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); }