Advertisement
Guest User

A*

a guest
Nov 13th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.21 KB | None | 0 0
  1. class Node():
  2.     """A node class for A* Pathfinding"""
  3.  
  4.     def __init__(self, parent=None, position=None):
  5.         self.parent = parent
  6.         self.position = position
  7.  
  8.         self.g = 0
  9.         self.h = 0
  10.         self.f = 0
  11.  
  12.     def __eq__(self, other):
  13.         return self.position == other.position
  14.  
  15.     def __str__(self):
  16.         return "no(" + str(self.position) + "," + str(self.parent) + ")"
  17.  
  18.  
  19. def astar(maze, start, end):
  20.     """Returns a list of tuples as a path from the given start to the given end in the given maze"""
  21.     # Create start and end node
  22.     start_node = Node(None, start)
  23.     start_node.g = start_node.h = start_node.f = 0
  24.     end_node = Node(None, end)
  25.     end_node.g = end_node.h = end_node.f = 0
  26.  
  27.     # Initialize both open and closed list
  28.     open_list = []
  29.     closed_list = []
  30.  
  31.     # Add the start node
  32.     open_list.append(start_node)
  33.     i = 0
  34.     # Loop until you find the end
  35.     while len(open_list) > 0:
  36.        
  37.         # Get the current node
  38.         current_node = open_list[0]
  39.         current_index = 0
  40.         for index, item in enumerate(open_list):
  41.             if item.f < current_node.f:
  42.                 current_node = item
  43.                 current_index = index
  44.  
  45.         # Pop current off open list, add to closed list
  46.         open_list.pop(current_index)
  47.         closed_list.append(current_node)
  48.        
  49.         # Found the goal
  50.         if current_node == end_node:
  51.             path = []
  52.             current = current_node
  53.             while current is not None:
  54.                 path.append(current.position)
  55.                 current = current.parent
  56.             return path[::-1] # Return reversed path
  57.        
  58.         # Generate children
  59.         children = []
  60.         for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0)]: # Adjacent squares
  61.            
  62.             # Get node position
  63.             node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
  64.  
  65.             # Make sure within range
  66.             if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
  67.                 continue
  68.  
  69.             # Make sure walkable terrain
  70.             if maze[node_position[0]][node_position[1]] != 0:
  71.                 continue
  72.  
  73.             # Create new node
  74.             new_node = Node(current_node, node_position)
  75.  
  76.             # Append
  77.             children.append(new_node)
  78.        
  79.         # Loop through children
  80.         for child in children:
  81.             # Child is on the closed list
  82.             for closed_child in closed_list:
  83.                 if child == closed_child:
  84.                     continue
  85.  
  86.             # Create the f, g, and h values
  87.             child.g = current_node.g + 1
  88.             child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2)
  89.             child.f = child.g + child.h
  90.  
  91.             # Child is already in the open list
  92.             for open_node in open_list:
  93.                 if child == open_node and child.g > open_node.g:
  94.                     continue
  95.  
  96.             # Add the child to the open list
  97.             open_list.append(child)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement