public Path GetPathBetweenRegions(Region startRegion, Region endRegion, IPathFindingRegionSelector regionSelector, IPathFindingCostCalculator costCalculator) { List <Region> closedSet = new List <Region>(); List <Region> openSet = new List <Region> { startRegion }; Dictionary <int, Region> cameFrom = new Dictionary <int, Region>(); //key - regionID, value - region from which it came Dictionary <int, double> gScore = new Dictionary <int, double>(); Dictionary <int, double> fScore = new Dictionary <int, double>(); foreach (var region in Persistent.Regions.GetAll()) { gScore.Add(region.ID, double.MaxValue); fScore.Add(region.ID, double.MaxValue); } gScore[startRegion.ID] = 0; fScore[startRegion.ID] = 0;// EstimateDistance(startRegion, endRegion); while (openSet.Count != 0) { var currentID = GetKeyWithMinimumValueInOpenSet(fScore, openSet); var current = Persistent.Regions.First(r => r.ID == currentID); if (currentID == endRegion.ID) { return(reconstructPath(cameFrom, startRegion, current, gScore[currentID])); } RemoveFrom(openSet, current); closedSet.Add(current); var neighbours = current.GetNeighbours(); List <int> enemiesIDs = new List <int>(); List <int> embargoIDs = new List <int>(); foreach (var neighbour in neighbours) { if (closedSet.Contains(neighbour.Region)) { continue; } if (regionSelector.IsPassableRegion(neighbour) == false) { closedSet.Add(neighbour.Region); continue; } double tentative_gScore = gScore[current.ID] + costCalculator.CalculatePassageCost(neighbour.Passage); if (openSet.Contains(neighbour.Region) == false) { openSet.Add(neighbour.Region); } else if (tentative_gScore >= gScore[neighbour.Region.ID]) { continue; } cameFrom[neighbour.Region.ID] = current; gScore[neighbour.Region.ID] = tentative_gScore; fScore[neighbour.Region.ID] = tentative_gScore; } } return(null); //No path }
public Path GetPathBetweenRegions(Region startRegion, Region endRegion, IPathFindingRegionSelector regionSelector) { return(GetPathBetweenRegions(startRegion, endRegion, regionSelector, new DefaultPassageCostCalculator(this))); }