def load_map(self, map): startx, starty, endx, endy, self.search_thread.map = self.gui_grid.load_map( map) self.gui_grid.calculate_rect_size(self.window.size[0], self.window.size[1]) self.start = dict(position=search_map.Position(startx, starty), added=True) self.end = dict(position=search_map.Position(endx, endy), added=True)
def clear_start_end(self): if self.start["added"]: self.gui_grid.push_grid_value(self.start["position"].x, self.start["position"].y, grid.Grid.NO_WALL_ID) self.start["position"] = search_map.Position(-1, -1) self.start["added"] = False if self.end["added"]: self.gui_grid.push_grid_value(self.end["position"].x, self.end["position"].y, grid.Grid.NO_WALL_ID) self.end["position"] = search_map.Position(-1, -1) self.end["added"] = False
def choose_start_end(self, x, y): if not self.start["added"]: self.start["position"] = search_map.Position(x, y) self.start["added"] = True self.gui_grid.push_grid_value(self.start["position"].x, self.start["position"].y, grid.Grid.START_END_ID) elif not self.end["added"]: self.end["position"] = search_map.Position(x, y) self.end["added"] = True self.gui_grid.push_grid_value(self.end["position"].x, self.end["position"].y, grid.Grid.START_END_ID) else: self.prompt_message("Start and Goal already chosen", "WARNING")
def modify_wall(self, x, y): if not self.gui_grid.is_valid_position(x, y): return position = search_map.Position(x, y) if position == self.start["position"] or position == self.end[ "position"]: return if self.add: self.gui_grid.push_grid_value(x, y, grid.Grid.WALL_ID) else: self.gui_grid.pop_grid_value(x, y, grid.Grid.WALL_ID)
def remove_start_end(self, x, y): pos = search_map.Position(x, y) if self.start["position"] != pos and self.end["position"] != pos: return False if self.start["added"] and self.end["added"]: # If start is clicked, swap it's position with end if self.start["position"] == pos: self.end["position"], self.start["position"] = self.start[ "position"], self.end["position"] # Remove end self.gui_grid.pop_grid_value(self.end["position"].x, self.end["position"].y, grid.Grid.START_END_ID) self.end["position"] = search_map.Position(-1, -1) self.end["added"] = False elif self.start["added"]: self.gui_grid.pop_grid_value(self.start["position"].x, self.start["position"].y, grid.Grid.START_END_ID) self.start["position"] = search_map.Position(-1, -1) self.start["added"] = False
def __init__(self): self.window = Window() self.is_done = False self.clock = pygame.time.Clock() self.current_time = 0 self.input_lock = False self.heuristic = heuristic.Heuristic.euclidian_distance self.epsilon = 1.0 self.message_queue = queue.Queue() self.time_limited = True self.limit = -1 # Create thread for searching if self.prompt_algorithm(): while self.limit == -1: self.limit = self.prompt_time_limit() self.search_thread = search_thread.ARAThread( limit=self.limit, message_queue=self.message_queue) self.epsilon = 3.0 else: self.search_thread = search_thread.AStarThread( message_queue=self.message_queue) self.time_limited = False self.search_thread.heuristic = self.heuristic self.search_thread.epsilon = self.epsilon # Check whether to add or remove walls self.add = True # Start point and End point self.start = dict(position=search_map.Position(-1, -1), added=False) self.end = dict(position=search_map.Position(-1, -1), added=False) # Create grid for drawing self.gui_grid = grid.Grid(50) self.gui_grid.calculate_rect_size(self.window.size[0], self.window.size[1])
def search_map(map, heuristic, epsilon=1, message_queue=None): # Create a map for checking if a block is in queue check_map = utilities.Utilities.create_matrix(map.size, -1) check_map[map.start.x][map.start.y] = 0 # Run algorithm path_found = False open_list = [] queue = PriorityQueue() # Lock user input if message_queue != None: message_queue.put_nowait(message.Message(action="LOCK")) # Clear path if message_queue != None: message_queue.put_nowait(message.Message(action="CLEAR")) node = SearchNode(map.start, None) queue.push(node, heuristic(map.start, map.end)) while not queue.empty(): node = queue.pop() # Request drawing if message_queue != None: pop_message = message.Message(action="PUSH", param=grid.Grid.POP_ID) pop_message.x = node.data.position.x pop_message.y = node.data.position.y message_queue.put_nowait(pop_message) node = node.data x = node.position.x y = node.position.y if not map.is_valid(x, y) or map.is_wall(x, y): break open_list.append(node) # If current node is end, stop if x == map.end.x and y == map.end.y: path_found = True break g_value = check_map[x][y] + 1 dxdyrange = [ (-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), ] for (dx, dy) in dxdyrange: tempx = x + dx tempy = y + dy # Child is a wall or not valid if not map.is_valid(tempx, tempy) or map.is_wall(tempx, tempy): continue # Child is already in queue and has smaller g(x) if check_map[tempx][tempy] != -1 and check_map[tempx][ tempy] <= g_value: continue # Otherwise, add child to queue check_map[tempx][tempy] = g_value child_pos = search_map.Position(tempx, tempy) f_value = g_value + heuristic(child_pos, map.end) * epsilon queue.push(SearchNode(child_pos, node), f_value) # Request drawing if message_queue != None: in_queue_message = message.Message( action="PUSH", param=grid.Grid.IN_QUEUE_ID) in_queue_message.x = tempx in_queue_message.y = tempy message_queue.put_nowait(in_queue_message) return map, open_list, path_found
def __init__(self, position=search_map.Position(), parent=None): self.position = position self.parent = parent