public static List<Point> PathToPill(Maze maze, Point start, Point destination) { var list = new List<Point>(); var closedSet = new List<PathNode>(); var hScore = Math.Abs(start.X - destination.X) + Math.Abs(start.Y - destination.Y); var openSet = new List<PathNode> { new PathNode { Position = start, GScore = 0, HScore = hScore, FScore = hScore } }; while (openSet.Count != 0) { var current = BestNode(openSet); if (current.Position.Equals(destination)) { list.Add(new Point { X = current.GScore }); list.Add(ReconstructPath(start, current).Position); return list; } openSet.Remove(current); closedSet.Add(current); var childpoints = GenerateMoves(maze, current.Position); foreach (var childpoint in childpoints) { var gScore = current.GScore + 1; hScore = Math.Abs(childpoint.X - destination.X) + Math.Abs(childpoint.Y - destination.Y); var newChild = new PathNode { Position = childpoint, GScore = gScore, HScore = hScore, FScore = gScore + hScore }; if (closedSet.Contains(newChild)) continue; var _newChild = FindChild(newChild, openSet); if (_newChild != null && gScore < _newChild.GScore) { openSet.Remove(_newChild); current.InsertChild(newChild); openSet.Add(newChild); } else if (_newChild == null) { current.InsertChild(newChild); openSet.Add(newChild); } } } return list; }
private static PathNode ReconstructPath(Point start, PathNode current) { while (current.Parent.Position != start) current = current.Parent; return current; }
private static bool isChildExplored(PathNode root, Point childPoint) { while (root != null) { if (root.Position == childPoint) return true; root = root.Parent; } return false; }
private static PathNode FindChild(PathNode newChild, List<PathNode> openSet) { foreach (var node in openSet) if (node.Position == newChild.Position) return node; return null; }
public static Point SelectPath(Maze maze, Point start, int depth) { var openSet = new List<PathNode> { new PathNode{Position = start} }; var closedSet = new List<PathNode>(); var _depth = 0; while (openSet.Count != 0 && _depth < depth) { var root = openSet.First(); openSet.Remove(root); var childPoints = GenerateMoves(maze, root.Position); foreach (var childPoint in childPoints) { if (!isChildExplored(root, childPoint)) { var _case = maze.GetSymbol(childPoint); switch (_case) { case '.': var newChild = new PathNode { Position = childPoint, Score = root.Score + 1 }; root.InsertChild(newChild); openSet.Add(newChild); break; case '*': newChild = new PathNode { Position = childPoint, Score = root.Score + 10 }; root.InsertChild(newChild); openSet.Add(newChild); break; default: break; } } } closedSet.Add(root); _depth++; } var current = new PathNode(); if (openSet.Count != 0) { current = closedSet.OrderByDescending(pathNode => pathNode.Score).First(); return ReconstructPath(start, current).Position; } current = closedSet.OrderByDescending(pathNode => pathNode.Score).First(); var longestStreaks = closedSet.Where(pathNode => pathNode.Score == current.Score).ToList(); if (longestStreaks.Count == 1) return ReconstructPath(start, current).Position; var random = new Random(); var longestStreakIndex = random.Next(0, longestStreaks.Count); return ReconstructPath(start, longestStreaks[longestStreakIndex]).Position; }
public void InsertChild(PathNode newChild) { newChild.parent = this; }