private void AddAdjacentNodes(Node node) { Node neighbour; AdjacentNode an; foreach (Edge edge in node.Edges) { neighbour = GetNeighbourNode(node, edge); if (cbDirectedGraph.Checked && neighbour != edge.DestNode) { continue; } if ((node.EdgeCameFrom == null || neighbour != GetNeighbourNode(node, node.EdgeCameFrom))) { if (!_sptSet.Contains(neighbour)) { if (_adjacentNodes.HasNode(neighbour)) { if (node.TotalCost + edge.Distance < neighbour.TotalCost) { an = _adjacentNodes.GetAdjacentNode(neighbour); an.EdgeCameFrom = edge; } } else { an = new AdjacentNode(neighbour, edge); _adjacentNodes.AddAdjacentNode(an); } } } } }
public TerrainNode[] FindPath(Vector3 start_position, Transform target_transform) { TerrainNode start_node = terrain_nodes_list.FindClosestTerrainNodeToPoint(start_position); TerrainNode target_node = terrain_nodes_list.FindTerrainNodeFromTransform(target_transform); //print (target_node.transform.name); AdjacentNode closest_node_to_target = new AdjacentNode(start_node, Vector3.Distance(start_node.position, target_node.position)); Heap <TerrainNode> open_set = new Heap <TerrainNode>(terrain_size); HashSet <TerrainNode> closed_set = new HashSet <TerrainNode>(); open_set.Add(start_node); //start_node.transform.gameObject.GetComponent<Renderer>().material = mat_start; //target_node.transform.gameObject.GetComponent<Renderer>().material = mat_target; // A* pathfinding algorithm while (open_set.Count > 0) { TerrainNode current_node = open_set.RemoveFirst(); closed_set.Add(current_node); //current_node.transform.gameObject.GetComponent<Renderer>().material = mat_path; if (current_node == target_node) { return(RetracePath(start_node, target_node)); } foreach (AdjacentNode adj_neighbour in current_node.GetAdjecentNodesArray()) { TerrainNode neighbour = adj_neighbour.terrain_node; if (closed_set.Contains(neighbour)) { continue; } float new_movement_cost_to_new_neighbour = current_node.g_cost + adj_neighbour.distance; if (new_movement_cost_to_new_neighbour < neighbour.g_cost || !open_set.Contains(neighbour)) { neighbour.g_cost = new_movement_cost_to_new_neighbour; neighbour.h_cost = Vector3.Distance(neighbour.position, target_node.position); neighbour.parent = current_node; if (!open_set.Contains(neighbour)) { open_set.Add(neighbour); } else { open_set.UpdateItem(neighbour); } if (neighbour.h_cost < closest_node_to_target.distance) { closest_node_to_target = new AdjacentNode(neighbour, neighbour.h_cost); } } } } // no path found, return the closest node to target return(FindPath(start_position, closest_node_to_target.transform)); }
// Given a list of TerrainNodes, this populates/updates the TerrainNodes's adjacent_nodes list // max_distance is the max distance the beacon is willing to travel per turn public static void SortAdjacentNodes(List <TerrainNode> terrain_node_list, float max_distance) { for (int i = 0; i < terrain_node_list.Count; i++) { for (int j = i; j < terrain_node_list.Count; j++) { float distance = Vector3.Distance(terrain_node_list[i].position, terrain_node_list[j].position); if (distance <= max_distance && distance > 0.0f) { terrain_node_list[i].AddAdjecentNode(new AdjacentNode(terrain_node_list[j], distance)); terrain_node_list[j].AddAdjecentNode(new AdjacentNode(terrain_node_list[i], distance)); } } AdjacentNode.SortAdjacentNodes(terrain_node_list[i].GetAdjecentNodesArray()); } }
public void AddAdjecentNode(AdjacentNode adjacent_node) { adjacent_node_list.Add(adjacent_node); }