void reconstruct_path( Dictionary <Path_Node <Tile>, Path_Node <Tile> > Came_From, Path_Node <Tile> current ) { // So at this point, current IS the goal. // So what we want to do is walk backwards through the Came_From // map, until we reach the "end" of that map...which will be // our starting node! var total_path = new Queue <Tile>(); total_path.Enqueue(current.data); // This "final" step is the path is the goal! while (Came_From.ContainsKey(current)) { // Came_From is a map, where the // key => value relation is real saying // some_node => we_got_there_from_this_node current = Came_From[current]; total_path.Enqueue(current.data); } // At this point, total_path is a queue that is running // backwards from the END tile to the START tile, so let's reverse it. _path = new Queue <Tile>(total_path.Reverse()); }
float heuristic_cost_estimate(Path_Node <Tile> a, Path_Node <Tile> b) { return((float)Math.Sqrt( Math.Pow(a.data.X - b.data.X, 2) + Math.Pow(a.data.Y - b.data.Y, 2) )); }
float dist_between(Path_Node <Tile> a, Path_Node <Tile> b) { // We can make assumptions because we know we're working // on a grid at this point. // Hori/Vert neighbours have a distance of 1 if (Math.Abs(a.data.X - b.data.X) + Math.Abs(a.data.Y - b.data.Y) == 1) { return(1f); } // Diag neighbours have a distance of 1.41421356237 if (Math.Abs(a.data.X - b.data.X) == 1 && Math.Abs(a.data.Y - b.data.Y) == 1) { return(1.41421356237f); } // Otherwise, do the actual math. return((float)Math.Sqrt( Math.Pow(a.data.X - b.data.X, 2) + Math.Pow(a.data.Y - b.data.Y, 2) )); }
public Path_TileGraph(World world) { //Debug.Log("Path_TileGraph"); // Loop through all tiles of the world // For each tile, create a node // Do we create nodes for non-floor tiles? NO! // Do we create nodes for tiles that are completely unwalkable (i.e. walls)? NO! nodes = new Dictionary <Tile, Path_Node <Tile> >(); for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x, y); //if(t.MovementCost > 0) { // Tiles with a move cost of 0 are unwalkable Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); //} } } //Debug.Log("Path_TileGraph: Created "+nodes.Count+" nodes."); // Now loop through all nodes again // Create edges for neighbours int edgeCount = 0; foreach (Tile t in nodes.Keys) { Path_Node <Tile> n = nodes[t]; List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); // Get a list of neighbours for the tile Tile[] neighbours = t.GetNeighbours(true); // NOTE: Some of the array spots could be null. // If neighbour is walkable, create an edge to the relevant node. for (int i = 0; i < neighbours.Length; i++) { if (neighbours[i] != null && neighbours[i].MovementCost > 0) { // This neighbour exists and is walkable, so create an edge. // But first, make sure we're not clipping a diagonal or trying to squeeze innapropriately if (IsClippingCorner(t, neighbours[i])) { continue; // don't add this tile. } Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbours[i].MovementCost; e.node = nodes[neighbours[i]]; // Add the edge to our temporary (and growable!) list edges.Add(e); edgeCount++; } } n.edges = edges.ToArray(); } //Debug.Log("Path_TileGraph: Created "+edgeCount+" edges."); }