//---------------------------------------------------------------------------- // Generate Path //---------------------------------------------------------------------------- #region GeneratePath /// <summary> /// Generic A* pathfinding, hex distance as heuristic /// </summary> public MapPath GeneratePath(IHexagon hex_a, IHexagon hex_b) { SortedSet <IPathValue> openSet = new SortedSet <IPathValue>(); PathValueDict = new Dictionary <IHexagon, IPathValue>(); Start = hex_a; Destination = hex_b; IPathValue firstPath = GetPathValue(hex_a); firstPath.SetFirstPathDistance(); openSet.Add(firstPath); while (openSet.Count != 0) { IPathValue currentPath = openSet.Min; openSet.Remove(currentPath); IHexagon currentHex = currentPath.Hex; if (currentHex.MyHexMap.CoOrds == hex_b.MyHexMap.CoOrds) { return(currentPath.ReconstructPath()); } foreach (IHexagon neighbour in currentHex.MyHexMap.Neighbours) { if (!neighbour.MyHexMap.IsOccupied()) { IPathValue neighbourPath = GetPathValue(neighbour); int newGScore = currentPath.Score_g + neighbour.MyHexMap.MovementCost; if (newGScore < neighbourPath.Score_g) { if (openSet.Contains(neighbourPath)) { openSet.Remove(neighbourPath); } neighbourPath.UpdateValues(newGScore, currentPath); openSet.Add(neighbourPath); } } } } return(null); }
//---------------------------------------------------------------------------- // Hexes in Range //---------------------------------------------------------------------------- /// <summary> /// This is an almost direct copy of above, but it sets the heuristic distance to /// to the start location <para/> /// /// So in practice it is Dijkstra's out until range /// </summary> public HashSet <IHexagon> GetHexesInRange(IHexagon start, int range) { SortedSet <IPathValue> openSet = new SortedSet <IPathValue>(); HashSet <IHexagon> hexesInRange = new HashSet <IHexagon>(); PathValueDict = new Dictionary <IHexagon, IPathValue>(); Destination = start; Start = start; IPathValue firstPath = GetPathValue(start); firstPath.SetFirstPathDistance(); openSet.Add(firstPath); while (openSet.Count != 0) { IPathValue currentPath = openSet.Min; openSet.Remove(currentPath); IHexagon currentHex = currentPath.Hex; hexesInRange.Add(currentHex); foreach (IHexagon neighbour in currentHex.MyHexMap.Neighbours) { if (!neighbour.MyHexMap.IsOccupied()) { IPathValue neighbourPath = GetPathValue(neighbour); int newGScore = currentPath.Score_g + neighbour.MyHexMap.MovementCost; if (newGScore < neighbourPath.Score_g && newGScore <= range) { if (openSet.Contains(neighbourPath)) { openSet.Remove(neighbourPath); } neighbourPath.UpdateValues(newGScore, currentPath); openSet.Add(neighbourPath); } } } } return(hexesInRange); }