protected void PrintShortestPath() { //Print the path of points from source to target WalkNode walkNode = target; pathFromSourceToTarget = new List <WalkNode>(); while (walkNode != null) { pathFromSourceToTarget.Add(walkNode); walkNode = walkNode.CameFrom; } Console.WriteLine("The shortest path between start point {0} and end point {1} in the maze loaded is:\n", source.ToString(), target.ToString()); pathFromSourceToTarget.Reverse(); string shortestPath = ""; foreach (WalkNode point in pathFromSourceToTarget) { shortestPath = string.Concat(shortestPath, string.Concat(point.ToString(), ",")); } shortestPath = "[" + shortestPath.Remove(shortestPath.Length - 1) + "]"; Console.WriteLine(shortestPath); Console.WriteLine(); }
private void AddNeighbors(WalkNode current) { WalkNode leftNeighbor = GetWalkNode(current.X - 1, current.Y);; WalkNode topNeighbor = GetWalkNode(current.X, current.Y - 1);; WalkNode topLeftNeighbor = GetWalkNode(current.X - 1, current.Y - 1); //Handle axial neighbors if (leftNeighbor != null) { current.AddNeighbor(leftNeighbor); leftNeighbor.AddNeighbor(current); } if (topNeighbor != null) { current.AddNeighbor(topNeighbor); topNeighbor.AddNeighbor(current); } if (topLeftNeighbor == null) { return; } //Handle diagonal neighbors if (topNeighbor != null && leftNeighbor != null) { current.AddNeighbor(topLeftNeighbor); topLeftNeighbor.AddNeighbor(current); leftNeighbor.AddNeighbor(topNeighbor); topNeighbor.AddNeighbor(leftNeighbor); } }
public void AddNeighbor(WalkNode neighbor) { if (neighbor == null) { return; } neighbors.Add(neighbor); }
public WalkNode(int x, int y) { this.id = BuildId(x, y); this.x = x; this.y = y; visited = false; cost = null; cameFrom = null; neighbors = new List <WalkNode>(); }
public int?calculateCostTo(WalkNode neighbor) { /** * Because all F's are the only spaces to walk, let's return the same cost for all of them: 1 * if there were another spaces that allowed movement like grass, water, etc; we could assign a * higher or lower cost than the walk spaces so the path finding algorithm takes such cost into * account to calculate the best route */ return(1); }
private void PrintNeigborsOf(string nodeId) { try { WalkNode walkNode = walkNodes[nodeId]; walkNode.PrintNeighbors(); } catch (Exception exc) { Console.WriteLine("Exception printing neighbors of node {0} : {1}", nodeId, exc.Message); } }
public override void GetShortestPath() { if (source == null || target == null) { Console.WriteLine("The start point and/or end points do not exist in the graph"); return; } source.Cost = 0; Queue <WalkNode> queue = new Queue <WalkNode>(); queue.Enqueue(source); while (queue.Count > 0) { WalkNode current = queue.Dequeue(); if (current == target) { break; } foreach (WalkNode neighbor in current.Neighbors) { int?newCost = current.Cost + neighbor.calculateCostTo(neighbor); if (neighbor.Cost == null || newCost < neighbor.Cost) { neighbor.Cost = newCost; neighbor.CameFrom = current; queue.Enqueue(neighbor); } } } if (target.CameFrom == null) { Console.WriteLine("The end point {0} is unreachable from start point {1}", target.ToString(), source.ToString()); return; } PrintShortestPath(); }
static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; string mapFile = defaultMapFile; int[] startPoint = defaultStartPoint; int[] endPoint = defaultEndPoint; /** * if you want to provide arguments to this console program, go to "Release" folder and edit * the Program.bat file. For example: * * start Maze.exe "Hound Maze(tsv).txt" 54 77 12 20 * * As you can see the parameters are passed in this order: * "filename" startPointX startpointY endPointX endPointY */ ReadArguments(args, ref mapFile, ref startPoint, ref endPoint); Maze maze = new Maze(mapFile); if (!maze.ConvertMazeFileToGraph()) { Console.ReadKey(); return; } WalkNode source = maze.GetWalkNode(startPoint); WalkNode target = maze.GetWalkNode(endPoint); PathFinding pathFinding = new Dijkstra(source, target); pathFinding.GetShortestPath(); maze.ConvertGraphSolvedToMazeFile(pathFinding); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
public bool ConvertMazeFileToGraph() { string mapFullPath = Path.Combine(Directory.GetCurrentDirectory(), mazeFile); try { mazeFileLines = File.ReadAllLines(mapFullPath); } catch (Exception exc) { Console.WriteLine("Error reading the map file <{0}> : {1}", mazeFile, exc.Message); mazeFileLines = null; } if (mazeFileLines == null) { return(false); } for (int y = 0; y < mazeFileLines.Length; y++) { string line = mazeFileLines[y]; string[] nodes = line.Split('\t'); for (int x = 0; x < nodes.Length; x++) { string node = nodes[x]; if (node == "F") { WalkNode walkNode = new WalkNode(x - xOffset, y - yOffset); AddNeighbors(walkNode); walkNodes[walkNode.Id] = walkNode; } } } return(true); }
public Dijkstra(WalkNode source, WalkNode target) : base(source, target) { }
public void PrintNeigborsOf(int x, int y) { string nodeId = WalkNode.BuildId(x, y); PrintNeigborsOf(nodeId); }
public WalkNode GetWalkNode(int x, int y) { string nodeId = WalkNode.BuildId(x, y); return(GetWalkNode(nodeId)); }
public void ConvertGraphSolvedToMazeFile(PathFinding pathFinding) { List <string> solvedMapLines = new List <string>(); for (int y = 0; y < mazeFileLines.Length; y++) { string line = mazeFileLines[y]; string[] nodes = line.Split('\t'); for (int x = 0; x < nodes.Length; x++) { string node = nodes[x]; if (node != "F") { continue; } WalkNode walkNode = GetWalkNode(x - xOffset, y - yOffset); if (walkNode == null) { continue; } if (!pathFinding.PathFromSourceToTarget.Contains(walkNode)) { continue; } if (walkNode == pathFinding.Source) { nodes[x] = startPointMarker; } else if (walkNode == pathFinding.Target) { nodes[x] = endPointMarker; } else { nodes[x] = betweenPointMarker; } } solvedMapLines.Add(string.Join("\t", nodes)); } string solvedMap = Path.GetFileNameWithoutExtension(mazeFile) + "_Solved.txt"; string solvedMapFullPath = Path.Combine(Directory.GetCurrentDirectory(), solvedMap); try { File.WriteAllLines(solvedMapFullPath, solvedMapLines); } catch (Exception exc) { Console.WriteLine("Error writing the solved map file {0} : {1}", mazeFile, exc.Message); return; } Console.WriteLine("A new maze file <{0}> has been generated in folder {1} to show the shortest path:\n", solvedMap, Directory.GetCurrentDirectory()); Console.WriteLine("Start Point marked with {0}", startPointMarker); Console.WriteLine("End Point marked with {0}", endPointMarker); Console.WriteLine("In-Between points are marked with {0}", betweenPointMarker); Console.WriteLine(); }
public PathFinding(WalkNode source, WalkNode target) { this.source = source; this.target = target; pathFromSourceToTarget = new List <WalkNode>(); }