Advertisement
Guest User

Untitled

a guest
Nov 27th, 2014
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.11 KB | None | 0 0
  1. import maze
  2. import mazeIO
  3. import sys
  4. #the deque class supports pops from both ends
  5. from collections import deque
  6.  
  7. ###A class for solving mazes###
  8.  
  9. class MazeSolver:
  10.  
  11. #Initializes the solver with the maze to solve
  12. #The maze class contains (see maze.py):
  13. # 1) matrix: the matrix of characters ('W', 'O', 'B', or 'E')
  14. # representing the maze
  15. # 2) start: the starting square as [row, column]
  16. # 3) end: the ending square as [row, column]
  17. def __init__(self, maze):
  18.  
  19. self.maze = maze
  20.  
  21. #Solves a maze.
  22. #search_type can be either DFS or BFS,
  23. #depending on whether you want the maze solved
  24. #using depth first search or breadth first search,
  25. #respectively.
  26. #
  27. #Returns a path through the maze as a list of [row, column]
  28. #squares where path[0] = maze.start and
  29. #path[len(path)-1] = maze.end
  30. #For every square i, path[i] should be adjacent to
  31. #path[i+1] and maze.matrix[i] should not be 'W'
  32. #
  33. #Also returns all the nodes expanded as a [row, column]
  34. #list. These need not be in any particular order and
  35. #should include the nodes on the path.
  36.  
  37. def solve_maze(self, search_type):
  38. def explore(point): #(y,x)
  39. newly_explored = []
  40. if (point[1]>=1): #go left
  41. newly_explored.append([point[0],point[1]-1])
  42. if (point[1]<=self.maze.rows-2): #go right
  43. newly_explored.append([point[0],point[1]+1])
  44. if (point[0]>=1): #go up
  45. newly_explored.append([point[0]-1,point[1]])
  46. if (point[0]<=self.maze.cols-2): #go down
  47. newly_explored.append([point[0]+1,point[1]])
  48. return newly_explored
  49. def search_DFS(cur, pathing):
  50. if (len(pathing)>0):
  51. pathing.insert(0,cur)
  52. else:
  53. pathing.append(cur)
  54. if (cur==self.maze.start):
  55. return pathing
  56. expanded.append(cur)
  57. newer = explore(cur)
  58. for node in newer:
  59. if (node not in expanded and self.maze.matrix[node[0]][node[1]] != "W"):
  60. new_pathing = pathing[:] #shallowcopy this list
  61. res = search_DFS(node, new_pathing)
  62. if (res!=[]):
  63. return res
  64. return []
  65. def search_BFS(end):
  66. i=0
  67. cur = end
  68. pathing = [[cur]]
  69. while (expanded[-1] != cur or cur==end):
  70. cur = expanded[i]
  71. if (cur==self.maze.start):
  72. return pathing[i]
  73. newer = explore(cur)
  74. for node in newer:
  75. if (node not in expanded and self.maze.matrix[node[0]][node[1]] != "W"):
  76. expanded.append(node)
  77. pathing.append([]) #shallow copy path
  78. for path in pathing[i]:
  79. pathing[-1].append(path)
  80. pathing[-1].insert(0,node)
  81. i+=1
  82. return []
  83.  
  84.  
  85. if (search_type != "DFS" and search_type != "BFS"):
  86. print "Invalid search type"
  87. return [], []
  88.  
  89. if (self.maze.start == []):
  90. print "Maze does not have starting square"
  91. return [], []
  92.  
  93. if (self.maze.end == []):
  94. print "Maze does not have ending square"
  95. return [], []
  96.  
  97. path = []
  98. expanded = []
  99.  
  100. #######################################
  101. ############YOUR CODE HERE#############
  102. #######################################
  103. if (search_type=="DFS"):
  104. path = search_DFS(self.maze.end, [])
  105. else:
  106. expanded.append(self.maze.end)
  107. path = search_BFS(self.maze.end)
  108.  
  109. #print path
  110. return path, expanded
  111.  
  112. #This main function will allow you to test your maze solver
  113. #by printing your solution to a ppm image file or ascii text file.
  114. #
  115. #Usage: maze_solver input_filename output_filename <image scaling>
  116. #
  117. #You must specify the input file name and the output file name.
  118. #The input should be a .ppm or .txt file in the form output by
  119. #the mazeIO class. See test_maze.ppm and many_paths.txt for examples.
  120. #
  121. #You also need to specify a search type:
  122. #BFS: solves the maze using breadth first search
  123. #DFS: solves the maze using depth first search
  124. #
  125. #For small mazes, a one-to-one
  126. #correspondence between maze squares and pixels will be too small to see
  127. #(ie a 10x10 maze gives an image of 10x10 pixels)
  128. #so the ppm image is scaled when written out. If you are trying to
  129. #read in a scaled ppm image, you MUST specify image scaling to be
  130. #the correct scaling or you will get a very strange looking solution.
  131. #For example, the scaling used to print out test_maze.ppm was 6 so
  132. #to solve test_maze.ppm using breadth first search and write it out to
  133. #test_path.ppm you would use:
  134. #
  135. #python maze_solver_skeleton.py test_maze.ppm test_path.ppm BFS 6
  136. #
  137. #If you read in an image, the same scaling will be used to output the
  138. #image so in the example test_path.ppm will also be scaled by a factor
  139. #of 6. The actual maze is 50x50 so both ppm images are 300x300 pixels.
  140. #
  141. #You may read in a maze as a text file and output it as an image file or
  142. #vice-versa. If you read a maze in as a text file, you can specify a
  143. #scaling just for the output file.
  144.  
  145. def main(argv):
  146.  
  147. if (len(argv) < 4):
  148. print "Usage: maze_solver input_file output_file search-type <image scaling>"
  149. return
  150. infilename = argv[1]
  151. innameparts = infilename.split('.')
  152. if (len(innameparts) != 2 or (innameparts[1] != "ppm" \
  153. and innameparts[1] != "txt")):
  154. print "Must enter an input file name ending in .ppm or .txt"
  155. return
  156. outfilename = argv[2]
  157. outnameparts = outfilename.split('.')
  158. if (len(outnameparts) != 2 or (outnameparts[1] != "ppm" \
  159. and outnameparts[1] != "txt")):
  160. print "Must enter an output file name ending in .ppm or .txt"
  161. return
  162. if (argv[3] != "DFS" and argv[3] != "BFS"):
  163. print "Please enter valid search type. Choose one of: BFS, DFS"
  164. return
  165. searchtype = argv[3]
  166. scaling = 1
  167. if (len(argv) > 4):
  168. try:
  169. scaling = int(argv[4])
  170. except:
  171. scaling = 1
  172. if (scaling <= 0):
  173. scaling = 1
  174. if (innameparts[1] == "ppm"):
  175. maze = mazeIO.ppmIO.read_maze_from_ppm(infilename, scaling)
  176. else:
  177. maze = mazeIO.asciiIO.read_maze_from_ascii(infilename)
  178. solver = MazeSolver(maze)
  179. path, expanded = solver.solve_maze(searchtype)
  180. print "Length of path:", len(path), \
  181. "\nNumber of nodes expanded: ", len(expanded)
  182. if (outnameparts[1] == "ppm"):
  183. mazeIO.ppmIO.write_visited_to_ppm(outfilename, maze, expanded, path, scaling)
  184. else:
  185. mazeIO.asciiIO.write_visited_to_ascii(outfilename, maze, expanded, path)
  186.  
  187. if __name__ == "__main__":
  188. main(sys.argv)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement