class Scene: def __init__(self): self.reset(gen_uuid()) def update(self, nodes): current_time = rospy.Time.now() for node in nodes: node.last_update.data = current_time if node.parent not in self.__nodes: node.parent = self.root_id() self.__nodes.update(nodes) return [n.id for n in nodes if n.name != "root"] def remove(self, ids): self.__nodes.remove(ids) return ids def root_id(self): return self.__root_id def nodes(self): return self.__nodes def reset(self, root_id): self.__root_id = root_id if not hasattr(self, '__nodes'): node_ids = [] self.__nodes = Nodes() else: node_ids = self.__nodes.ids() self.__nodes.reset() root = Node(id=self.__root_id, name="root") root.position.pose.orientation.w = 1.0 self.__nodes.update([root]) return node_ids
if Menu.maze_generation_dict["Prim"]: t1 = threading.Thread(target=randomized_prims_algorithm, args=(Nodes.nodeList, )) t1.start() Menu.maze_generation_dict["Prim"] = False Button.inactivate("Prim") elif Menu.maze_generation_dict["Recursive Division"]: t1 = threading.Thread(target=recursive_division, args=(Nodes.nodeList, )) t1.start() Menu.maze_generation_dict["Recursive Division"] = False Button.inactivate("Recursive Division") if Menu.bool_and_method_dict["GO!"]: Nodes.reset() k = 0 for key in Menu.algorithms_dict: if Menu.algorithms_dict[key] is True: t1 = threading.Thread(target=method_dict[key], args=(Nodes.nodeList, )) t1.start() else: k += 1 if k == len(Menu.algorithms_dict): t1 = threading.Thread(target=dijkstra, args=(Nodes.nodeList, )) t1.start() Menu.bool_and_method_dict["GO!"] = False Button.inactivate("GO!") for node in Nodes.nodeList:
def randomized_prims_algorithm(nodes): # Creates a 2D array so it's easier to handle as a grid. maze = [] maze_width = Nodes.width maze_height = Nodes.height for i in range(maze_height): maze.append([ node for node in Nodes.nodeList[i * maze_width:(i + 1) * maze_width] ]) # Makes all nodes to walls so we can connect a path through. The alternative is to first run the algorithm below # and then backtrack it and build the walls. Because there won't be a very distinct pattern with Prim's # randomized algorithm I think it'll look nicer this way. Nodes.reset() for node in nodes: node.is_Wall = True node.color = black # Chooses a random coordinate in the grid, the node which the path will originate from. y = random.randrange(0, maze_height) x = random.randrange(0, maze_width) # List to keep track of which walls have been erased (made non-walls). Later this list will also carry the # coordinates of nodes which should not be erased, i.e. nodes, which if erased, would connect two different # parts of the maze. For obvious reasons this is not wanted. erased = [] maze[y][x].erase() erased.append((x, y)) # Creates a list of connected walls (meaning that, if we were to erase them, they'd connect to another non-wall). connected_walls = [] # Creates a list of neighbor-coordinates (or rather the difference between neighbors # and the first randomized node, that being (x, y)). directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # In this program a path cannot be diagonal. # Iterates over every direction for dx, dy in directions: # Makes sure that neighbor-coordinate is within the grid. if -1 < x + dx < maze_width and -1 < y + dy < maze_height: connected_walls.append((x + dx, y + dy)) # This is where the magic happens. while len(connected_walls) > 0: # Chooses a random index within the length of connected_walls list. index = random.randrange(0, len(connected_walls)) # Picks out the coordinate (made random by index, which is randomly selected). xy_coord = connected_walls[index] # Removes the chosen coordinate from the list, it can only be picked once. # Alternative: connected_walls.pop(index); though the return is not needed. del connected_walls[index] # Splits coordinate into x and y. x, y = xy_coord[0], xy_coord[1] # Erases (makes non-wall) the node at the given coordinate, and adds it to the erased list. maze[y][x].erase() erased.append((x, y)) # Again, creates a list of possible ways to travel and iterates over the list. directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] for dx, dy in directions: if -1 < x + dx < maze_width and -1 < y + dy < maze_height: # If the neighbor-coordinate has not been erased and is not already in connected_walls list, # then it should be added. if (x + dx, y + dy) not in erased and not ( x + dx, y + dy) in connected_walls: connected_walls.append((x + dx, y + dy)) # If it already is in the connected_walls list, this means that it should never be erased, since # that would connect two different parts of the maze. Therefore, if that is the case, it is removed # and added to the erased list, so that if it is encountered again it gives False for the above if- # - statement, making sure that it will never again be added to the connected_walls list. elif (x + dx, y + dy) in connected_walls: connected_walls.remove((x + dx, y + dy)) erased.append((x + dx, y + dy)) # Pauses the algorithm so that the interface is cleaner. time.sleep(0.01)