def simple_maze( screen, grid, start, end ): Speed = utility.Speed #_____used for the random generation of 0 and 1 with 25-75 ratio_____# weighted_random = [0, 1, 1, 1] #_____loop through all the nodes of the grid_____# for i in range(NO_OF_BOXS): for j in range(NO_OF_BOXS): #_____Make changes according to the position of the node_____# if utility.is_start_or_end( (i, j), start, end ) : continue if i==0 or j==0 or i==NO_OF_BOXS-1 or j==NO_OF_BOXS-1: grid[ i ][ j ].cell_type = 'Wall' else: new_cell_type = choice(weighted_random) if new_cell_type == 0 : grid[ i ][ j ].cell_type = 'Wall' #_____Mark the changes that were made in the loop_____# for i in range(NO_OF_BOXS): for j in range(NO_OF_BOXS): time.sleep(0.025*Speed) utility.make_change(screen, grid, i, j) utility.draw_grid(screen)
def make_opening( screen, grid, x, y, width, height, wall_x, wall_y ): opening = [] #_____Possible openings_____# possible_open = [(randint(x, wall_x -1), wall_y), (randint(wall_x + 1, x + width -1), wall_y),(wall_x, randint(y, wall_y -1)), (wall_x, randint(wall_y + 1, y + height - 1))] #_____Positions of the margin exactly beside the created wall_____# margin_open = [(x, wall_y), (x+width-1, wall_y), (wall_x, y), (wall_x, y + height-1)] #_____Positions of the nodes adjecent to margin nodes_____# adj_open = [(x-1, wall_y), (x+width, wall_y), (wall_x, y - 1), (wall_x, y + height)] #_____Check if created walls have margin positions adjencet ot thme____# #_____If yes then open the respective adj position_____# for i in range(4): adj_x, adj_y = (adj_open[i][0], adj_open[i][1]) if utility.is_within_the_grid( grid ,adj_x, adj_y ) and not utility.is_wall( grid, adj_x, adj_y ): grid[margin_open[i][0]][margin_open[i][1]].cell_type = 'Blank' utility.make_change(screen, grid, margin_open[i][0], margin_open[i][1]) else: opening.append( possible_open[i] ) ignore_it = randint( 0, len(possible_open)-1 ) for i in range(len(opening)): if i != ignore_it: grid[opening[i][0]][opening[i][1]].cell_type = 'Blank' utility.make_change(screen, grid, opening[i][0], opening[i][1]) utility.draw_grid(screen)
def a_star(screen, grid, start, end): Speed = utility.Speed neighbour = [(1, 0), (-1, 0), (0, -1), (0, 1)] visited = [] q = PriorityQueue() #_____Add START node to PriorityQueue_____# grid[start[0]][start[1]].g_score = 0 grid[start[0]][start[1]].h_score = h(start, end) grid[start[0]][start[1]].score = h(start, end) q.put((grid[start[0]][start[1]].score, start)) #_____Loop while there is an element in this PriorityQueue_____# while not q.empty(): utility.draw_grid(screen) time.sleep(0.025 * Speed) #_____Get the topmost element of the PriorityQueue_____# curr_tup = q.get() curr = curr_tup[1] if curr == end: print("ALL_DONE") break if is_visited(visited, curr): continue visited.append(curr) if curr != start and curr != end: grid[curr[0]][curr[1]].cell_type = 'Lead' utility.make_change(screen, grid, curr[0], curr[1]) temp_g_score = grid[curr[0]][curr[1]].g_score + 1 #_____Traverse all the neighbours of 'curr'_____# for nb in neighbour: new_x = curr[0] + nb[0] new_y = curr[1] + nb[1] #_____Check if this node (is_within_the_grid) and (is_not_a_wall) and (is_not_visited)_____# #_____And have less overall score(distance) than previous of its score Then add this node to PriorityQueue with new overall score(distance)_____# #_____overall score(distance) = g_function + h_function_____# if utility.is_within_the_grid(grid, new_x, new_y): condition = (grid[new_x][new_y].score > (temp_g_score + h( (new_x, new_y), end))) if not utility.is_wall(grid, new_x, new_y) and condition: grid[new_x][new_y].g_score = temp_g_score grid[new_x][new_y].h_score = h((new_x, new_y), end) grid[new_x][new_y].score = grid[new_x][ new_y].g_score + grid[new_x][new_y].h_score grid[new_x][new_y].pre_cell = curr q.put((grid[new_x][new_y].score, (new_x, new_y))) if not utility.is_start_or_end((new_x, new_y), start, end): grid[new_x][new_y].cell_type = 'Span' utility.make_change(screen, grid, new_x, new_y) #_____mark_the_final_path_____# utility.mark_the_final_path(screen, grid, start, end)
def do_Recursive_Backtracking( screen, grid, start, end, width, height ): Speed = utility.Speed #_____Randomly generate a start node and make it open_____# maze_start = (randint(0, width-1), randint(0, height-1)) grid[2*maze_start[0] + 1][2*maze_start[1] + 1].cell_type = 'Blank' utility.make_change(screen, grid, 2*maze_start[0] + 1, 2*maze_start[1] + 1) utility.draw_grid(screen) #_____Adding this start node to queue and looping while there is an element in the queue_____# check_list = [] check_list.append(maze_start) while len(check_list): time.sleep(0.025*Speed) top_entry = check_list[-1] if not check_adj_pos( screen, grid, top_entry[0], top_entry[1], width, height, check_list ): check_list.remove(top_entry)
def bfs(screen, grid, start, end): Speed = utility.Speed neighbour = [(1, 0), (-1, 0), (0, -1), (0, 1)] found = False q = [] #_____Add START node to Queue_____# q.append(start) #_____Loop while there is an element in this queue_____# while len(q) > 0: time.sleep(0.025 * Speed) utility.draw_grid(screen) if found: break #_____Get the first element of the queue_____# curr = q[0] q.pop(0) grid[curr[0]][curr[1]].cell_type = 'Lead' if not utility.is_start_or_end(curr, start, end): utility.make_change(screen, grid, curr[0], curr[1]) for nb in neighbour: #_____Traverse all the neighbours of 'curr'_____# new_x = curr[0] + nb[0] new_y = curr[1] + nb[1] #_____Check if this node (is_within_the_grid) and (is_not_a_wall) and (is_not_visited)_____# #_____Then add this node to queue_____# if utility.is_within_the_grid(grid, new_x, new_y): if (not utility.is_wall(grid, new_x, new_y)) and ( utility.is_not_visited(grid, new_x, new_y)): grid[new_x][new_y].pre_cell = curr q.append((new_x, new_y)) if not utility.is_start_or_end((new_x, new_y), start, end): grid[new_x][new_y].cell_type = 'Span' utility.make_change(screen, grid, new_x, new_y) if (new_x, new_y) == end: found = True break #_____mark_the_final_path_____# utility.mark_the_final_path(screen, grid, start, end)
def dfs(screen, grid, start, end): Speed = utility.Speed neighbour = [(0, 1), (-1, 0), (0, -1), (1, 0)] parent_cell = (0, 0) q = deque() #_____Add START node to Stack_____# q.append(start) #_____Loop while there is an element in this stack_____# while len(q): utility.draw_grid(screen) time.sleep(0.025 * Speed) #_____Get the topmost element of the stack_____# curr = q.pop() #_____Check if this node (is_not_a_wall) and (is_not_visited)_____# #_____Then add this node to stack_____# if (not utility.is_wall(grid, curr[0], curr[1])) and ( utility.is_not_visited(grid, curr[0], curr[1])): grid[curr[0]][curr[1]].pre_cell = parent_cell parent_cell = curr if curr == end: break elif curr != start: grid[curr[0]][curr[1]].cell_type = 'Lead' utility.make_change(screen, grid, curr[0], curr[1]) #_____Traverse all the neighbours of 'curr'_____# for nb in neighbour: new_x = curr[0] + nb[0] new_y = curr[1] + nb[1] #_____Check if this node (is_within_the_grid) and (is_not_a_wall) and (is_not_visited)_____# #_____Then add this node to stack_____# if utility.is_within_the_grid(grid, new_x, new_y): if (not utility.is_wall(grid, new_x, new_y)) and ( utility.is_not_visited(grid, new_x, new_y)): q.append((new_x, new_y)) #_____mark_the_final_path_____# utility.mark_the_final_path(screen, grid, start, end)
def Recursive_Backtracking( screen, grid, start, end ): Speed = utility.Speed #_____loop through all the nodes of the grid and make them WALL_____# for i in range(NO_OF_BOXS//2 + 1): for j in range(NO_OF_BOXS): if (i,j)==start or (i,j)==end : continue grid[ i ][ j ].cell_type = 'Wall' utility.make_change(screen, grid, i, j) utility.draw_grid(screen) if (NO_OF_BOXS-1-i,NO_OF_BOXS-1-j)==start or (NO_OF_BOXS-1-i,NO_OF_BOXS-1-j)==end : continue grid[ NO_OF_BOXS-1-i ][ NO_OF_BOXS-1-j ].cell_type = 'Wall' utility.make_change(screen, grid, NO_OF_BOXS-1-i, NO_OF_BOXS-1-j) utility.draw_grid(screen) #_____do_Recursive_Backtracking_____# do_Recursive_Backtracking( screen, grid, start, end, (NO_OF_BOXS-1)/2, (NO_OF_BOXS-1)/2 )
def Recursive_Division( screen ,grid, start, end ): Speed = utility.Speed #_____Mark the edges the grid as WALLS_____# for x in range(NO_OF_BOXS): time.sleep(0.025*Speed) grid[ x ][ 0 ].cell_type = 'Wall' grid[ x ][ NO_OF_BOXS-1 ].cell_type = 'Wall' utility.make_change( screen, grid, x, 0 ) utility.make_change( screen, grid, x, NO_OF_BOXS-1 ) #_____Mark the edges the grid as WALLS_____# for y in range(NO_OF_BOXS): time.sleep(0.025*Speed) grid[ 0 ][ y ].cell_type = 'Wall' grid[ NO_OF_BOXS-1 ][ y ].cell_type = 'Wall' utility.make_change( screen, grid, 0, y ) utility.make_change( screen, grid, NO_OF_BOXS-1, y ) #_____do_Recursive_Division_____# do_Recursive_Division( screen ,grid, start, end, (1, 1), NO_OF_BOXS-2, NO_OF_BOXS-2 )
def do_Recursive_Division( screen ,grid, start, end, d, width, height ): Speed = utility.Speed def get_wall_index( corner, length ): assert length >= 3 wall_pos = randint( corner+1, corner+length-2 ) if wall_pos%2 == 1: wall_pos -= 1 return wall_pos def make_opening( screen, grid, x, y, width, height, wall_x, wall_y ): opening = [] #_____Possible openings_____# possible_open = [(randint(x, wall_x -1), wall_y), (randint(wall_x + 1, x + width -1), wall_y),(wall_x, randint(y, wall_y -1)), (wall_x, randint(wall_y + 1, y + height - 1))] #_____Positions of the margin exactly beside the created wall_____# margin_open = [(x, wall_y), (x+width-1, wall_y), (wall_x, y), (wall_x, y + height-1)] #_____Positions of the nodes adjecent to margin nodes_____# adj_open = [(x-1, wall_y), (x+width, wall_y), (wall_x, y - 1), (wall_x, y + height)] #_____Check if created walls have margin positions adjencet ot thme____# #_____If yes then open the respective adj position_____# for i in range(4): adj_x, adj_y = (adj_open[i][0], adj_open[i][1]) if utility.is_within_the_grid( grid ,adj_x, adj_y ) and not utility.is_wall( grid, adj_x, adj_y ): grid[margin_open[i][0]][margin_open[i][1]].cell_type = 'Blank' utility.make_change(screen, grid, margin_open[i][0], margin_open[i][1]) else: opening.append( possible_open[i] ) ignore_it = randint( 0, len(possible_open)-1 ) for i in range(len(opening)): if i != ignore_it: grid[opening[i][0]][opening[i][1]].cell_type = 'Blank' utility.make_change(screen, grid, opening[i][0], opening[i][1]) utility.draw_grid(screen) #_____If any side of input box is less 2 than return_____# if width <= 1 or height <= 1: return #_____Randomly generate wall position_____# wall_x, wall_y = (get_wall_index( d[0], width ), get_wall_index( d[1], height )) #_____Create walls at Randomly generated position_____# for i in range( d[0], d[0]+width ): time.sleep(0.025*Speed) if (i,wall_y)==start or (i,wall_y)==end : continue grid[i][wall_y].cell_type = 'Wall' utility.make_change(screen, grid, i, wall_y) utility.draw_grid(screen) #_____Create walls at Randomly generated position_____# for i in range( d[1], d[1]+height ): time.sleep(0.025*Speed) if utility.is_start_or_end((wall_x,i), start, end) : continue grid[wall_x][i].cell_type = 'Wall' utility.make_change(screen, grid, wall_x, i) utility.draw_grid(screen) #_____Make openings_____# make_opening( screen, grid, d[0], d[1], width, height, wall_x, wall_y ) time.sleep(0.025*Speed) #_____Recursive calls_____# do_Recursive_Division( screen ,grid, start, end, d, wall_x-d[0], wall_y-d[1] ) do_Recursive_Division( screen ,grid, start, end, (d[0], wall_y+1), wall_x-d[0], d[1]+height-wall_y-1 ) do_Recursive_Division( screen ,grid, start, end, (wall_x+1, d[1]), d[0]+width-wall_x-1, wall_y-d[1] ) do_Recursive_Division( screen ,grid, start, end, (wall_x+1, wall_y+1), d[0]+width-wall_x-1, d[1]+height-wall_y-1 )
def check_adj_pos( screen, grid, x, y, width, height, check_list ): direction = [] #_____If x>0 and (x-1) is within the grid and not visited then we can move to left, thus append it to the queue_____# if x > 0: if not is_open(grid, 2*(x-1)+1, 2*y+1): direction.append( 'L' ) #_____If y>0 and (y-1) is within the grid and not visited then we can move to up, thus append it to the queue_____# if y > 0: if not is_open( grid, 2*x+1, 2*(y-1)+1 ): direction.append( 'U' ) #_____If (x < width-1) and (x+1) is within the grid and not visited then we can move to right, thus append it to the queue_____# if x < width-1 : if not is_open(grid, 2*(x+1)+1, 2*y+1): direction.append( 'R' ) #_____If (y < height-1) and (y+1) is within the grid and not visited then we can move to down, thus append it to the queue_____# if y < height-1: if not is_open( grid, 2*x+1, 2*(y+1)+1 ): direction.append( 'D' ) #_____If there is any element in the queue, mark them open in there respective direction and return_____# if len(direction): chosen_dir = choice(direction) if chosen_dir == 'L': check_list.append( (x-1, y) ) grid[2*x][2*y+1].cell_type = 'Blank' grid[2*(x-1)+1][2*y+1].cell_type = 'Blank' utility.make_change(screen, grid, 2*x, 2*y+1) utility.make_change(screen, grid, 2*(x-1)+1, 2*y+1) utility.draw_grid(screen) elif chosen_dir == 'U': check_list.append( (x, y-1) ) grid[2*x+1][2*(y-1)+1].cell_type = 'Blank' grid[2*x+1][2*y].cell_type = 'Blank' utility.make_change(screen, grid, 2*x+1, 2*(y-1)+1) utility.make_change(screen, grid, 2*x+1, 2*y) utility.draw_grid(screen) elif chosen_dir == 'R': check_list.append( (x+1, y) ) grid[2*x+2][2*y+1].cell_type = 'Blank' grid[2*(x+1)+1][2*y+1].cell_type = 'Blank' utility.make_change(screen, grid, 2*x+2, 2*y+1) utility.make_change(screen, grid, 2*(x+1)+1, 2*y+1) utility.draw_grid(screen) elif chosen_dir == 'D': check_list.append( (x, y+1) ) grid[2*x+1][2*y+2].cell_type = 'Blank' grid[2*x+1][2*(y+1)+1].cell_type = 'Blank' utility.make_change(screen, grid, 2*x+1, 2*y+2) utility.make_change(screen, grid, 2*x+1, 2*(y+1)+1) utility.draw_grid(screen) return True else: return False
if event.type == pygame.QUIT: run = False #_____Check if the Mouse Button is pressed_____# elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: count_click += 1 drag = True mouse_x, mouse_y = event.pos pos_x = mouse_x // WIDTH_PER_BOX pos_y = mouse_y // HEIGHT_PER_BOX #_____If its the first click, then this Node is the START Node_____# if count_click == 1: if utility.is_within_the_grid(grid, pos_x, pos_y): start = (pos_x, pos_y) grid[pos_x][pos_y].cell_type = "Start" utility.make_change(screen, grid, pos_x, pos_y) #_____If the click is outside of the grid, then its not considered for changing the grid_____# else: count_click -= 1 #_____If its the second click, then this Node is the END Node_____# elif count_click == 2: if utility.is_within_the_grid(grid, pos_x, pos_y): end = (pos_x, pos_y) grid[pos_x][pos_y].cell_type = "End" utility.make_change(screen, grid, pos_x, pos_y) #_____If the click is outside of the grid, then its not considered for changing the grid_____# else: count_click -= 1 elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: drag = False