public List <Node> Solve(Maze maze) { Node start = maze.GetStart(); Node end = maze.GetEnd(); int width = maze.width; List <Node> stack = new List <Node>(); stack.Add(start); Node[] prev = new Node[maze.height * maze.width]; bool[] visited = new bool[maze.height * maze.width]; for (int i = 0; i < visited.Length; i++) { visited[i] = false; } completed = false; Node current; while (stack.Count > 0) { current = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); if (current == end) { completed = true; break; } visited[current.Position().Y *width + current.Position().X] = true; foreach (var n in current.neighbours) { if (n != null) { int npos = n.Position().Y *width + n.Position().X; if (visited[npos] == false) { stack.Add(n); prev[npos] = current; } } } } List <Node> path = new List <Node>(); path.Add(end); current = end; while (current != null) { path = DirectionFactory.AppendLeft(path, current); current = prev[current.Position().Y *width + current.Position().X]; } return(path); }
public List <Node> Solve(Maze maze) { int width = maze.width; int total = maze.width * maze.height; var start = maze.GetStart(); var startPos = start.Position(); var end = maze.GetEnd(); var endPos = end.Position(); bool[] visited = new bool[total]; Node[] prev = new Node[total]; var infinity = float.PositiveInfinity; float[] distances = new float[total]; var unvisited = new FibPQ(); FibNode[] nodeIndex = new FibNode[total]; for (var i = 0; i < total; i++) { visited[i] = false; distances[i] = infinity; } distances[start.Position().Y *width + start.Position().X] = 0; var startNode = new FibNode(0, start); nodeIndex[start.Position().Y *width + start.Position().X] = startNode; unvisited.insert(startNode); completed = false; while (unvisited.len() > 0) { var n = unvisited.RemoveMinimum(); var u = n.value; var uPos = u.Position(); var uPosIndex = uPos.Y * width + uPos.X; if (distances[uPosIndex] == infinity) { break; } if (uPos == endPos) { completed = true; break; } foreach (var v in u.neighbours) { if (v != null) { var vPos = v.Position(); var vPosIndex = vPos.Y * width + vPos.X; if (visited[vPosIndex] == false) { var d = (vPos.Y - uPos.Y) + (vPos.X - uPos.X); var newDistance = distances[uPosIndex] + d; var remaining = (vPos.Y - endPos.Y) + (vPos.X - endPos.X); if (newDistance < distances[vPosIndex]) { var vNode = nodeIndex[vPosIndex]; if (vNode == null) { vNode = new FibNode((int)newDistance + remaining, v); unvisited.insert(vNode); nodeIndex[vPosIndex] = vNode; distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } else { unvisited.decreaseKey(vNode, (int)newDistance + remaining); distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } } } } } visited[uPosIndex] = true; } List <Node> path = new List <Node>(); Node current = end; path.Add(current); while (current != null) { path = DirectionFactory.AppendLeft(path, current); current = prev[current.Position().Y *width + current.Position().X]; } return(path); }
public List <Node> Solve() { var width = maze.width; var total = maze.width * maze.height; var start = maze.GetStart(); var end = maze.GetEnd(); var endPos = end.Position(); bool[] visited = new bool[total]; Node[] prev = new Node[total]; var infinity = float.PositiveInfinity; float[] distances = new float[total]; FibNode[] nodeIndex = new FibNode[total]; for (var i = 0; i < total; i++) { visited[i] = false; distances[i] = infinity; } var unvisited = new FibPQ(); distances[start.Position().Y *width + start.Position().X] = 0; FibNode startNode = new FibNode(0, start); nodeIndex[start.Position().Y *width + start.Position().X] = startNode; unvisited.insert(startNode); int count = 0; completed = false; while (unvisited.len() > 0) { count += 1; FibNode n = unvisited.RemoveMinimum(); // Node u = n.value; Point uPos = u.Position(); int uPosIndex = uPos.Y * width + uPos.X; if (distances[uPosIndex] == infinity) { break; } if (uPos == endPos) { completed = true; break; } foreach (var v in u.neighbours) { if (v != null) { Point vPos = v.Position(); int vPosIndex = vPos.Y * width + vPos.X; if (visited[vPosIndex] == false) { int d = (vPos.Y - uPos.Y) + (vPos.X - uPos.X); int newDistance = (int)distances[uPosIndex] + d; if (newDistance < distances[vPosIndex]) { var vNode = nodeIndex[vPosIndex]; //v isn't alread in the queue - add it if (vNode == null) { vNode = new FibNode(newDistance, v); unvisited.insert(vNode); nodeIndex[vPosIndex] = vNode; distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } //v is already in the queue - decrease it's key else { unvisited.decreaseKey(vNode, newDistance); distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } } } } } visited[uPosIndex] = true; } //Recontruct the path. List <Node> path = new List <Node>(); Node current = end; path.Add(current); while (current != null) { path = DirectionFactory.AppendLeft(path, current); current = prev[current.Position().Y *width + current.Position().X]; } return(path); }