-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathalgorithms.py
More file actions
134 lines (109 loc) · 3.84 KB
/
algorithms.py
File metadata and controls
134 lines (109 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from random import shuffle
def DFS(maze):
"""
Return a complete maze using DFS.
"""
cellStack = []
if not maze.solution_path:
maze.start.set_visited()
cellStack.append(maze.start)
else:
# push all the cells from the solution path to the stack
for cell in maze.solution_path:
cell.set_visited()
cellStack.append(cell)
currentCell = maze.start
while cellStack:
neighbours = maze.get_neighbours(currentCell)
shuffle(neighbours)
for cell in neighbours:
if cell.visited == False: # choose a random unvisited cell
next_cell = cell
cellStack.append(currentCell)
next_cell.set_visited()
currentCell.remove_walls(next_cell)
currentCell = next_cell
break
else:
# if there are cells no that is not visited
currentCell = cellStack.pop()
return maze
def BFS(maze):
"""
Return a complete maze using BFS.
"""
n, m = maze.n, maze.m
queue = []
visited_path = {}
if not maze.solution_path:
queue = [maze.start]
visited_path[(maze.start.i, maze.start.j)] = 1
else:
for cell in maze.solution_path:
cell.set_visited()
queue.append(cell)
visited_path[(cell.i, cell.j)] = 1
parent = {}
while queue:
cur = queue.pop(0)
visited_path[(cur.i, cur.j)] = 1
if (len(visited_path) >= n * m):
break
neighbours = maze.get_neighbours(cur)
shuffle(neighbours)
for cell in neighbours:
# Randomly choose one valid adjacent cell
if (cell.i, cell.j) not in visited_path:
cur.remove_walls(cell)
queue.append(cell)
visited_path[(cell.i, cell.j)] = 1
parent[(cell.i, cell.j)] = (cur.i, cur.j)
break
# If there are no valid adjacent cells, we push the parent of the current cell into the queue
else:
if len(visited_path) < n * m:
if (cur.i, cur.j) in parent:
queue.append(maze.cell_at(*parent[(cur.i, cur.j)]))
return maze
def rBFS(maze, reduced=11/16):
"""
Return a complete maze using BFS.
"""
n, m = maze.n, maze.m
queue = []
visited_path = {}
if not maze.solution_path:
queue = [maze.start]
visited_path[(maze.start.i, maze.start.j)] = 1
else:
for cell in maze.solution_path:
queue.append(cell)
cell.set_visited()
visited_path[(cell.i, cell.j)] = 1
shuffle(queue)
saved_queue = queue[:int(reduced * len(queue))][:]
queue[:int(reduced * len(queue))] = []
parent = {}
while len(visited_path) < n * m: # Goal check
while queue:
cur = queue.pop(0)
visited_path[(cur.i, cur.j)] = 1
neighbours = maze.get_neighbours(cur)
shuffle(neighbours)
for cell in neighbours:
# Randomly choose one valid adjacent cell
if (cell.i, cell.j) not in visited_path:
cur.remove_walls(cell)
queue.append(cell)
visited_path[(cell.i, cell.j)] = 1
parent[(cell.i, cell.j)] = (cur.i, cur.j)
break
# If there are no valid adjacent cells, we push the parent of the current cell into the queue
else:
if len(visited_path) < n * m:
if (cur.i, cur.j) in parent:
queue.append(maze.cell_at(*parent[(cur.i, cur.j)]))
# If the queue is empty, we add a cell in the saved queue to the queue
if len(visited_path) < n * m:
queue.append(saved_queue.pop(0))
return maze