/// <summary> /// Finds the path. /// </summary> /// <param name="user">The user.</param> /// <param name="diag">if set to <c>true</c> [diag].</param> /// <param name="map">The map.</param> /// <param name="start">The start.</param> /// <param name="end">The end.</param> /// <returns>List<Vector2D>.</returns> public static List <Vector2D> FindPath(RoomUser user, bool diag, Gamemap map, Vector2D start, Vector2D end) { List <Vector2D> list = new List <Vector2D>(); PathFinderNode pathFinderNode = FindPathReversed(user, diag, map, start, end); if (pathFinderNode != null) { list.Add(end); while (pathFinderNode.Next != null) { list.Add(pathFinderNode.Next.Position); pathFinderNode = pathFinderNode.Next; } } return(list); }
/// <summary> /// Finds the path reversed. /// </summary> /// <param name="roomUserable">The user.</param> /// <param name="whatIsDiag">if set to <c>true</c> [diag].</param> /// <param name="gameLocalMap">The map.</param> /// <param name="startMap">The start.</param> /// <param name="endMap">The end.</param> /// <returns>PathFinderNode.</returns> public static PathFinderNode FindPathReversed(RoomUser roomUserable, bool whatIsDiag, Gamemap gameLocalMap, Vector2D startMap, Vector2D endMap) { MinHeap <PathFinderNode> minSpanTreeCost = new MinHeap <PathFinderNode>(256); PathFinderNode[,] pathFinderMap = new PathFinderNode[gameLocalMap.Model.MapSizeX, gameLocalMap.Model.MapSizeY]; PathFinderNode pathFinderStart = new PathFinderNode(startMap) { Cost = 0 }; PathFinderNode pathFinderEnd = new PathFinderNode(endMap); pathFinderMap[pathFinderStart.Position.X, pathFinderStart.Position.Y] = pathFinderStart; minSpanTreeCost.Add(pathFinderStart); while (minSpanTreeCost.Count > 0) { pathFinderStart = minSpanTreeCost.ExtractFirst(); pathFinderStart.InClosed = true; for (int index = 0; (whatIsDiag ? (index < DiagMovePoints.Length ? 1 : 0) : (index < NoDiagMovePoints.Length ? 1 : 0)) != 0; index++) { Vector2D realEndPosition = pathFinderStart.Position + (whatIsDiag ? DiagMovePoints[index] : NoDiagMovePoints[index]); bool isEndOfPath = (realEndPosition.X == endMap.X) && (realEndPosition.Y == endMap.Y); if (gameLocalMap.IsValidStep(roomUserable, new Vector2D(pathFinderStart.Position.X, pathFinderStart.Position.Y), realEndPosition, isEndOfPath, roomUserable.AllowOverride)) { PathFinderNode pathFinderSecondNodeCalculation; if (pathFinderMap[realEndPosition.X, realEndPosition.Y] == null) { pathFinderSecondNodeCalculation = new PathFinderNode(realEndPosition); pathFinderMap[realEndPosition.X, realEndPosition.Y] = pathFinderSecondNodeCalculation; } else { pathFinderSecondNodeCalculation = pathFinderMap[realEndPosition.X, realEndPosition.Y]; } if (!pathFinderSecondNodeCalculation.InClosed) { int internalSpanTreeCost = 0; if (pathFinderStart.Position.X != pathFinderSecondNodeCalculation.Position.X) { internalSpanTreeCost++; } if (pathFinderStart.Position.Y != pathFinderSecondNodeCalculation.Position.Y) { internalSpanTreeCost++; } int loopTotalCost = pathFinderStart.Cost + internalSpanTreeCost + pathFinderSecondNodeCalculation.Position.GetDistanceSquared(endMap); if (loopTotalCost < pathFinderSecondNodeCalculation.Cost) { pathFinderSecondNodeCalculation.Cost = loopTotalCost; pathFinderSecondNodeCalculation.Next = pathFinderStart; } if (!pathFinderSecondNodeCalculation.InOpen) { if (pathFinderSecondNodeCalculation.Equals(pathFinderEnd)) { pathFinderSecondNodeCalculation.Next = pathFinderStart; return(pathFinderSecondNodeCalculation); } pathFinderSecondNodeCalculation.InOpen = true; minSpanTreeCost.Add(pathFinderSecondNodeCalculation); } } } } } return(null); }