private static List <GridSquare> GetNeighbours(GridSquare from, char[,] maze, int targetx, int targety) { List <GridSquare> result = new List <GridSquare>(); if (from.Y - 1 >= 0 && maze[from.Y - 1, from.X] == '.') { GridSquare neighbour = new GridSquare(from.X, from.Y - 1, true); neighbour.Score = Math.Abs((from.X - targetx) + (from.Y - targety - 1)); neighbour.Parent = from; result.Add(neighbour); } if (from.Y + 1 < maze.GetLength(0) && maze[from.Y + 1, from.X] == '.') { GridSquare neighbour = new GridSquare(from.X, from.Y + 1, true); neighbour.Score = Math.Abs((from.X - targetx) + (from.Y - targety + 1)); neighbour.Parent = from; result.Add(neighbour); } if (from.X - 1 >= 0 && maze[from.Y, from.X - 1] == '.') { GridSquare neighbour = new GridSquare(from.X - 1, from.Y, true); neighbour.Score = Math.Abs((from.X - 1 - targetx) + (from.Y - targety)); neighbour.Parent = from; result.Add(neighbour); } if (from.X + 1 < maze.GetLength(1) && maze[from.Y, from.X + 1] == '.') { GridSquare neighbour = new GridSquare(from.X + 1, from.Y, true); neighbour.Score = Math.Abs((from.X + 1 - targetx) + (from.Y - targety)); neighbour.Parent = from; result.Add(neighbour); } return(result); }
public static int AStarPathFind(int fromX, int fromY, int targetX, int targetY, char[,] maze) { List <GridSquare> open_list = new List <GridSquare>(); List <GridSquare> closed_list = new List <GridSquare>(); open_list.Add(new GridSquare(fromX, fromY, true)); bool bTargetReachable = false; while (open_list.Count > 0) { GridSquare square = open_list.OrderBy(sq => sq.Score).First(); closed_list.Add(square); if (closed_list.Exists(sq => sq.X == targetX && sq.Y == targetY)) { bTargetReachable = true; break; } List <GridSquare> neighbours = GetNeighbours(square, maze, targetX, targetY); for (int i = 0; i < neighbours.Count; i++) { //In closed list? ignore! if (closed_list.Exists(sq => sq.X == neighbours[i].X && sq.Y == neighbours[i].Y)) { continue; } //In open list? if (open_list.Exists(sq => sq.X == neighbours[i].X && sq.Y == neighbours[i].Y)) { GridSquare update = open_list.Find(sq => sq.X == neighbours[i].X && sq.Y == neighbours[i].Y); if (neighbours[i].Score < update.Score) { update.Score = neighbours[i].Score; } } else { open_list.Add(neighbours[i]); } } open_list.Remove(square); } int steps = 0; if (bTargetReachable) { GridSquare target = closed_list.First(sq => sq.X == targetX && sq.Y == targetY); while (target.Parent != null) { //maze[target.Y, target.X] = 'O'; target = target.Parent; steps++; } } return(steps); }
public GridSquare(int x, int y, bool walkable) { X = x; Y = y; Walkable = walkable; Parent = null; Score = 0; }