public void Solve(IMazeGrid maze, Action <IEnumerable <IMazeCell> > solvedResultCallback) { Graph <IMazeCell> graph = maze.GenerateGraph(); // stack of graph nodes Stack <GraphNode <IMazeCell> > stack = new Stack <GraphNode <IMazeCell> >(); // Routes Collection LinkedList <GraphNode <IMazeCell> > visited = new LinkedList <GraphNode <IMazeCell> >(); GraphNode <IMazeCell> startNode = (GraphNode <IMazeCell>)graph.Nodes.FindByValue(maze.Start); stack.Push(startNode); GraphNode <IMazeCell> currentNode = null; while (stack.Count > 0) { currentNode = stack.Pop(); _logger.LogTrace($"Poped Node: {currentNode.Value.ToString()}"); if (visited.Contains(currentNode)) { continue; } visited.AddFirst(currentNode); if (maze.Finish.Equals(currentNode.Value)) { _logger.LogTrace($"Found Finish Node: {currentNode.Value.ToString()}"); solvedResultCallback(TraceSolvedPath(visited)); } // Examine neighbor nodes foreach (GraphNode <IMazeCell> neighbor in currentNode.Neighbors) { if (!visited.Contains(neighbor)) { stack.Push(neighbor); _logger.LogTrace($"Push Node: {neighbor.Value.ToString()}"); } else { _logger.LogTrace($"Node: {neighbor.Value.ToString()} is visited"); } } } }
public void Solve(IMazeGrid maze, Action <IEnumerable <IMazeCell> > solvedResultCallback) { Graph <IMazeCell> graph = maze.GenerateGraph(); // stack of graph nodes LinkedList <GraphNode <IMazeCell> > visited = new LinkedList <GraphNode <IMazeCell> >(); //collecting all routes GraphNode <IMazeCell> startNode = (GraphNode <IMazeCell>)graph.Nodes.FindByValue(maze.Start); GraphNode <IMazeCell> endNode = (GraphNode <IMazeCell>)graph.Nodes.FindByValue(maze.Finish); visited.AddFirst(startNode); // make the first call BreadthFirst(startNode, endNode, visited, solvedResultCallback); }
public void Solve(IMazeGrid maze, Action <IEnumerable <IMazeCell> > solvedResultCallback) { // the maze graph Graph <IMazeCell> graph = maze.GenerateGraph(); // List of Accepted solutions used to reset the visited nodes List <List <GraphNode <IMazeCell> > > solutions = new List <List <GraphNode <IMazeCell> > >(); // Que of graph nodes Queue <GraphNode <IMazeCell> > queue = new Queue <GraphNode <IMazeCell> >(); // Directory of Predecessor Dictionary <GraphNode <IMazeCell>, GraphNode <IMazeCell> > predecessors = new Dictionary <GraphNode <IMazeCell>, GraphNode <IMazeCell> >(); // List visited nodes List <GraphNode <IMazeCell> > visited = new List <GraphNode <IMazeCell> >(); GraphNode <IMazeCell> currentNode = null; GraphNode <IMazeCell> startNode = (GraphNode <IMazeCell>)graph.Nodes.FindByValue(maze.Start); queue.Enqueue(startNode); while (queue.Count > 0) { currentNode = queue.Dequeue(); _logger.LogTrace($"Dequeue Node({currentNode.Value.ToString()})"); if (visited.Contains(currentNode)) { continue; } visited.Add(currentNode); if (maze.Finish.Equals(currentNode.Value)) { _logger.LogTrace($"Finish Node({currentNode.Value.ToString()})"); IEnumerable <GraphNode <IMazeCell> > solvedPath = TraceSolvedPath(currentNode, predecessors); // callback Action and returns path. List <IMazeCell> cbPath = new List <IMazeCell>(); foreach (var node in solvedPath) { cbPath.Add(node.Value); } solvedResultCallback(cbPath); break; } foreach (GraphNode <IMazeCell> neighbor in currentNode.Neighbors) { if (!visited.Contains(neighbor) && !queue.Contains(neighbor)) { // enquew queue.Enqueue(neighbor); // keep track of Predecessor predecessors[neighbor] = currentNode; _logger.LogTrace($"Enqueue Node: {neighbor.Value.ToString()} Predecessor: {currentNode.Value.ToString()}"); } else { _logger.LogTrace($"Node({neighbor.Value.ToString()}) is visited"); } } } }
public void Solve(IMazeGrid maze, Action <IEnumerable <IMazeCell> > solvedResultCallback) { Graph <IMazeCell> graph = maze.GenerateGraph(); GraphNode <IMazeCell> startNode = (GraphNode <IMazeCell>)graph.Nodes.FindByValue(maze.Start); Dictionary <GraphNode <IMazeCell>, GraphNode <IMazeCell> > predecessors = new Dictionary <GraphNode <IMazeCell>, GraphNode <IMazeCell> >(); List <GraphNode <IMazeCell> > nodes = new List <GraphNode <IMazeCell> >(); Dictionary <GraphNode <IMazeCell>, int> distances = new Dictionary <GraphNode <IMazeCell>, int>(); GraphNode <IMazeCell> currentNode = null; // read all nodes and init distances foreach (GraphNode <IMazeCell> vertex in graph.Nodes) { // start node has 0 distance, all over nodes are unknown and set to Max if (vertex.Value.Equals(maze.Start)) { distances[vertex] = 0; } else { distances[vertex] = int.MaxValue; } nodes.Add(vertex); } while (nodes.Count != 0) { // Find current shortest path point to explore nodes.Sort((x, y) => distances[x] - distances[y]); currentNode = nodes[0]; nodes.Remove(currentNode); if (currentNode.Value.Equals(maze.Finish)) { IEnumerable <IMazeCell> solvedPath = TraceSolvedPath(currentNode, predecessors).Reverse(); solvedResultCallback(solvedPath); // Calls the callback Action and returns the path. break; } if (distances[currentNode] == int.MaxValue) { break; } foreach (GraphNode <IMazeCell> neighbor in currentNode.Neighbors) { var indx = currentNode.Neighbors.IndexOf(neighbor); // distance of current node + Neighbors Cost ( Cost = paths between nodes ) int newDistance = distances[currentNode] + currentNode.Costs[indx]; if (newDistance < distances[neighbor]) { distances[neighbor] = newDistance; predecessors[neighbor] = currentNode; } } } }