Advertisement
anubhav_c

ASCII Mazes with A* search

Mar 13th, 2012
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.31 KB | None | 0 0
  1. # Grid format:
  2. #   0 = Navigable space
  3. #   1 = Occupied space
  4.  
  5. import random
  6.  
  7. deltas = [(-1, 0 ), # go up
  8.         ( 0, -1), # go left
  9.         ( 1, 0 ), # go down
  10.         ( 0, 1 )] # go right
  11.  
  12. delta_names = ['^', '<', 'v', '>']
  13.  
  14. cost = 1
  15.  
  16. def search(grid, init, goal, cost, astar=True):
  17.     current = (0,) + init
  18.     open = [current]
  19.     closed = []
  20.     action = [[ '' for col in range(len(grid[0]))] for row in range(len(grid))]
  21.     resign = False
  22.    
  23.     if astar:
  24.         heuristic = generate_heuristic(grid, goal)
  25.     else:
  26.         heuristic = [[0 for x in range(len(grid[0]))] for y in range(len(grid))]
  27.    
  28.     while current[1:] != goal:
  29.         if not open: #no open nodes left
  30.             resign = True
  31.             current = (-1,) + current[1:]
  32.             break
  33.         #Find open node with smallest f = g + h
  34.         current = min(open, key= lambda (g, y, x): g + heuristic[y][x])
  35.         #first coordinate is y, not x
  36.         gcur, ycur, xcur = current
  37.         for d in zip(deltas, delta_names):
  38.             (dy, dx), direction = d
  39.             g, y, x = gcur + cost, ycur + dy, xcur + dx
  40.             if x<0 or y<0 or y>=len(grid) or x>=len(grid[0]):
  41.                 continue
  42.             elif (y,x) in closed or grid[y][x]==1: #already visited, or a wall
  43.                 continue
  44.             elif (y,x) in map(lambda node: node[1:], open): #already planning to visit
  45.                 continue
  46.             else:
  47.                 open.append((g, y, x))
  48.                 action[y][x] = direction
  49.        
  50.         open.remove((gcur,ycur,xcur))
  51.         closed.append((ycur, xcur))
  52.        
  53.     current_g, _, _ = current #cost of getting to goal
  54.    
  55.     #ASCII art for path
  56.     dir_dict = {}
  57.     for d in zip(deltas, delta_names):
  58.         delta, delta_name = d
  59.         dir_dict[delta_name] = delta
  60.    
  61.     roadmap = [[' ' for col in range (len(grid[0]))] for row in range(len(grid))]
  62.    
  63.     #add walls and visited nodes
  64.     for i in range(len(grid)):
  65.         for j in range(len(grid[0])):
  66.             if grid[i][j] == 1:
  67.                 roadmap[i][j] = 'H'
  68.             if (i,j) in closed:
  69.                 roadmap[i][j] = '.'
  70.    
  71.     #add path
  72.     path_y, path_x = ycur, xcur
  73.     if resign: #nowhere left to go
  74.         roadmap[path_y][path_x] = '?'
  75.     goal_y, goal_x = goal
  76.     roadmap[goal_y][goal_x] = '*'
  77.     while (path_y, path_x) != init:
  78.         motion = action[path_y][path_x]
  79.         path_dy, path_dx = dir_dict[motion]
  80.         path_y, path_x = path_y - path_dy, path_x - path_dx
  81.         roadmap[path_y][path_x] = motion
  82.    
  83.     #beautify
  84.     roadmap = map(lambda x: ' '.join(x), roadmap)
  85.     roadmap = map(lambda x: '| '+ x + ' |', roadmap)
  86.     roadmap = ['='*len(roadmap[0])] + roadmap + ['='*len(roadmap[0])]
  87.     return current_g, roadmap
  88.  
  89. def generate_grid(maxsize):
  90.     no_of_columns = random.randint(2, maxsize)
  91.     no_of_rows = random.randint(2,maxsize)
  92.     max_wall_percent = 25
  93.     cells_per_wall = 100/max_wall_percent
  94.  
  95.     grid = [ [0 for column in range(no_of_columns)] for row in range(no_of_rows)]
  96.     grid = map(lambda row: map(lambda entry: 1 if random.randint(1, cells_per_wall)%int(cells_per_wall)==0\
  97.         else 0, row), grid)
  98.  
  99.     while True:
  100.         init_y, init_x = random.randint(0, len(grid)-1), random.randint(0, len(grid[0])-1)
  101.         if grid[init_y][init_x] == 0: #initial position isn't a wall
  102.             break
  103.     init = (init_y, init_x)
  104.     while True:
  105.         goal_y, goal_x = random.randint(0, len(grid)-1), random.randint(0, len(grid[0])-1)
  106.         if grid[goal_y][goal_x] == 0 and (goal_y,goal_x) != init: #goal shouldn't be a wall, or same as start point
  107.             break
  108.     goal = (goal_y, goal_x)
  109.    
  110.     return grid, init, goal
  111.    
  112. def generate_heuristic(grid, goal):
  113.     heuristic = [ [-1 for column in range(len(grid[0]))] for row in range(len(grid))]
  114.     goal_y, goal_x = goal
  115.     for y in range(len(grid)):
  116.         for x in range(len(grid[0])):
  117.             heuristic[y][x] = abs(y-goal_y) + abs(x-goal_x)
  118.     return heuristic
  119.  
  120. grid, init, goal = generate_grid(20)
  121.  
  122. print "Without A*"
  123. steps, path= search(grid, init, goal, cost, False)
  124. for row in path:
  125.     print row
  126. print "cost: ", steps
  127. print
  128. print "With A*"
  129. steps, path= search(grid, init, goal, cost, True)
  130. for row in path:
  131.     print row
  132. print "cost:", steps
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement