public NodeConnection(PathfindingNode start, PathfindingNode end, double cost=1.0) : base() { Start = start; End = end; Cost = cost; }
public PathfindingNode GetOppositeNode(PathfindingNode fromNode) { if (fromNode == Start) { return End; } else if (fromNode == End) { return Start; } return null; }
public void RemoveAllConnectionsBetween(PathfindingNode nodeA, PathfindingNode nodeB) { for (int i = _connections.Count - 1; i >= 0; i--) { NodeConnection connection = _connections[i]; if (connection.ContainsNode(nodeA) && connection.ContainsNode(nodeB)) { _connections.RemoveAt(i); } } }
public void AddConnection(PathfindingNode nodeA, PathfindingNode nodeB, int cost) { if (!_nodes.Contains(nodeA)) { _nodes.Add(nodeA); } if (!_nodes.Contains(nodeB)) { _nodes.Add(nodeB); } NodeConnection connection = new NodeConnection(nodeA, nodeB, cost); _connections.Add(connection); }
public Boolean HasDirectConnectionBetween(PathfindingNode nodeA, PathfindingNode nodeB) { foreach (NodeConnection connection in _connections) { if (connection.Start == nodeA && connection.End == nodeB) { return true; } if (connection.Start == nodeB && connection.End == nodeA) { return true; } } return false; }
public void RemoveNode(PathfindingNode node) { // Remove the node _nodes.Remove(node); // Remove any connections that have the node in it for(int i=_connections.Count-1; i>= 0; i--) { NodeConnection connection = _connections[i]; if (connection.ContainsNode(node)) { _connections.RemoveAt(i); } } }
public void Run() { List<NodeConnection> connections = new List<NodeConnection>(); PathfindingNode nodeA = new PathfindingNode() { Identifier = "A" }; PathfindingNode nodeB = new PathfindingNode() { Identifier = "B" }; PathfindingNode nodeC = new PathfindingNode() { Identifier = "C" }; PathfindingNode nodeD = new PathfindingNode() { Identifier = "D" }; PathfindingNode nodeE = new PathfindingNode() { Identifier = "E" }; PathfindingNode nodeF = new PathfindingNode() { Identifier = "F" }; PathGraph pathFinder = new PathGraph(); pathFinder.AddConnection(nodeA, nodeB, 1); pathFinder.AddConnection(nodeA, nodeC, 4); pathFinder.AddConnection(nodeA, nodeD, 8); pathFinder.AddConnection(nodeB, nodeC, 6); pathFinder.AddConnection(nodeB, nodeC, 10); pathFinder.AddConnection(nodeC, nodeD, 3); pathFinder.AddConnection(nodeC, nodeE, 8); pathFinder.AddConnection(nodeD, nodeE, 1); pathFinder.RemoveAllConnectionsBetween(nodeA, nodeC); pathFinder.RemoveAllConnectionsBetween(nodeD, nodeE); List<PathfindingNode> fastestPath = pathFinder.FindRoute(nodeA, nodeE); if (fastestPath == null) { Console.WriteLine("No path found!"); } else { Console.WriteLine("Fastest route is:"); //while (fastestPath.Parent != null) //{ // Console.WriteLine(fastestPath.Node + " cost " + fastestPath.Cost); // fastestPath = fastestPath.Parent; //} for (int i = 0; i < fastestPath.Count; i++) { PathfindingNode node = fastestPath[i]; Console.WriteLine(i + ": " + node.Identifier); } } }
private List<PathfindingNode> DoFindRoute(List<NodeConnection> connections, PathfindingNode startNode, PathfindingNode endNode) { System.Diagnostics.Debug.WriteLine("PathGraph DoFindRoute(connections, startNode, endNode)"); DateTime startTime = DateTime.Now; PathStep destinationPoint = new PathStep() { Node = endNode, Cost = 0, Ancestor = null }; List<PathStep> visitedPoints = new List<PathStep>(); visitedPoints.Add(destinationPoint); List<PathStep> pointsLeftToVisit = GetNewMoveableCoordinatesFromPoint(destinationPoint, visitedPoints); List<PathStep> newPoints; PathStep startPoint = null; PathStep currentPoint = null; while (pointsLeftToVisit.Count > 0 && startPoint == null) { currentPoint = pointsLeftToVisit[0]; if (currentPoint.Node == startNode) { startPoint = currentPoint; } else { pointsLeftToVisit.RemoveAt(0); visitedPoints.Add(currentPoint); newPoints = GetNewMoveableCoordinatesFromPoint(currentPoint, visitedPoints); foreach (PathStep point in newPoints) { pointsLeftToVisit.Add(point); if (point.Node == startNode) { startPoint = point; break; } } } } if (startPoint == null) { return null; } // Then we could not find a path! List<PathfindingNode> path = new List<PathfindingNode>(); PathStep pathStep = startPoint; while (pathStep != null) { path.Add(pathStep.Node); pathStep = pathStep.Ancestor; } DateTime endTime = DateTime.Now; TimeSpan duration = endTime.Subtract(startTime); System.Diagnostics.Debug.WriteLine("PathGraph DoFindRoute duration: "+duration.TotalMilliseconds+"ms"); return path; }
public List<PathfindingNode> FindRoute(PathfindingNode start, PathfindingNode end) { return DoFindRoute(_connections, start, end); }
public List<NodeConnection> GetConnectionsForNode(List<NodeConnection> connections, PathfindingNode node) { List<NodeConnection> matchingConnections = new List<NodeConnection>(); foreach (NodeConnection connection in connections) { if (connection.ContainsNode(node)) { matchingConnections.Add(connection); } } return matchingConnections; }
public Boolean ConnectionsHasNode(List<NodeConnection> connections, PathfindingNode node) { foreach (NodeConnection connection in connections) { if (connection.ContainsNode(node)) { return true; } } return false; }
public void AddNode(PathfindingNode node) { _nodes.Add(node); }
public Boolean ContainsNode(PathfindingNode node) { return (Start == node || End == node); }
/// <summary> /// This method should be called when all of the traversable locations are entered. Note, do NOT place DOORs before calling /// this method. Doors require actions to be traversable, so they would block the path. /// </summary> private PathGraph GeneratePathfindingGraph() { DateTime startTime = DateTime.Now; PathGraph pathfindingGraph = new PathGraph(); //PathfindingNodes = new List<PathfindingNode>(); //PathfindingConnections = new List<NodeConnection>(); for (int y = 0; y < MAP_HEIGHT_IN_TILES; y++) { for (int x = 0; x < MAP_WIDTH_IN_TILES; x++) { String locationKey = GetKeyForLocation(x, y); MapTileList locationTiles = GetMapTilesForLocation(x, y); Boolean locationIsTraversable = true; Boolean isTraversableNorth = true; Boolean isTraversableEast = true; Boolean isTraversableSouth = true; Boolean isTraversableWest = true; foreach(MapTile tile in locationTiles) { // If we have already determined that all paths are blocked, then there's no sense looping any further. if (!locationIsTraversable || (!isTraversableNorth && !isTraversableEast && !isTraversableSouth && !isTraversableWest)) { break; } if (tile.BlocksMovement) { locationIsTraversable = false; } if (tile.BlocksNorth) { isTraversableNorth = false; } if (tile.BlocksEast) { isTraversableEast = false; } if (tile.BlocksSouth) { isTraversableSouth = false; } if (tile.BlocksWest) { isTraversableWest = false; } } if (locationIsTraversable) // Only add a node if the location itself may be moved on { System.Diagnostics.Debug.WriteLine("Location " + locationKey + " is traversable!"); PathfindingNode node = new PathfindingNode(locationKey); _pathfindingPoints[node] = new Point(x, y); pathfindingGraph.AddNode(node); // Look for connections in all directions: North, East, South, List<MapTile> connectingTiles; Point connectingLocation = null; String connectingKey = null; PathfindingNode connectingNode = null; Boolean isConnectionTraversable = false; if (y > 0 && isTraversableNorth) { connectingLocation = new Point(x, y - 1); connectingKey = GetKeyForPoint(connectingLocation); connectingNode = pathfindingGraph.FindNodeByIdentifier(connectingKey); if (connectingNode != null && !pathfindingGraph.HasDirectConnectionBetween(node, connectingNode)) { connectingTiles = GetMapTilesForPoint(connectingLocation); isConnectionTraversable = true; foreach (MapTile tile in connectingTiles) { if (tile.BlocksMovement || tile.BlocksSouth) { isConnectionTraversable = false; break; } } if (isConnectionTraversable) // If both connections are valid, then link them! { pathfindingGraph.AddConnection(node, connectingNode, 1); } } } if (y < MAP_HEIGHT_IN_TILES - 1 && isTraversableSouth) { connectingLocation = new Point(x, y + 1); connectingKey = GetKeyForPoint(connectingLocation); connectingNode = pathfindingGraph.FindNodeByIdentifier(connectingKey); if (connectingNode != null && !pathfindingGraph.HasDirectConnectionBetween(node, connectingNode)) { connectingTiles = GetMapTilesForPoint(connectingLocation); isConnectionTraversable = true; foreach (MapTile tile in connectingTiles) { if (tile.BlocksMovement || tile.BlocksNorth) { isConnectionTraversable = false; break; } } if (isConnectionTraversable) // If both connections are valid, then link them! { pathfindingGraph.AddConnection(node, connectingNode, 1); } } } if (x > 0 && isTraversableWest) { connectingLocation = new Point(x - 1, y); connectingKey = GetKeyForPoint(connectingLocation); connectingNode = pathfindingGraph.FindNodeByIdentifier(connectingKey); if (connectingNode != null && !pathfindingGraph.HasDirectConnectionBetween(node, connectingNode)) { connectingTiles = GetMapTilesForPoint(connectingLocation); isConnectionTraversable = true; foreach (MapTile tile in connectingTiles) { if (tile.BlocksMovement || tile.BlocksEast) { isConnectionTraversable = false; break; } } if (isConnectionTraversable) // If both connections are valid, then link them! { pathfindingGraph.AddConnection(node, connectingNode, 1); } } } if (x < MAP_WIDTH_IN_TILES-1 && isTraversableEast) { connectingLocation = new Point(x + 1, y); connectingKey = GetKeyForPoint(connectingLocation); connectingNode = pathfindingGraph.FindNodeByIdentifier(connectingKey); if (connectingNode != null && !pathfindingGraph.HasDirectConnectionBetween(node, connectingNode)) { connectingTiles = GetMapTilesForPoint(connectingLocation); isConnectionTraversable = true; foreach (MapTile tile in connectingTiles) { if (tile.BlocksMovement || tile.BlocksWest) { isConnectionTraversable = false; break; } } if (isConnectionTraversable) // If both connections are valid, then link them! { pathfindingGraph.AddConnection(node, connectingNode, 1); } } } } } } DateTime endTime = DateTime.Now; TimeSpan duration = endTime.Subtract(startTime); System.Diagnostics.Debug.WriteLine("CalculateNodesAndConnections duration: "+duration.TotalMilliseconds+"ms"); return pathfindingGraph; }
public Point GetPointForPathfindingNode(PathfindingNode node) { return _pathfindingPoints[node]; }