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); }
Esempio n. 10
0
		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;
		}
Esempio n. 11
0
		public Boolean ConnectionsHasNode(List<NodeConnection> connections, PathfindingNode node)
		{
			foreach (NodeConnection connection in connections)
			{
				if (connection.ContainsNode(node))
				{ return true; }
			}
			return false;
		}
Esempio n. 12
0
		public void AddNode(PathfindingNode node)
		{
			_nodes.Add(node);
		}
		public Boolean ContainsNode(PathfindingNode node)
		{
			return (Start == node || End == node);
		}
Esempio n. 14
0
		/// <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;
		}
Esempio n. 15
0
		public Point GetPointForPathfindingNode(PathfindingNode node)
		{
			return  _pathfindingPoints[node];
		}