|
1 | 1 | """algorithms.py module""" |
2 | 2 |
|
3 | 3 | import time |
4 | | -from queue import PriorityQueue |
| 4 | +from queue import PriorityQueue, Queue, LifoQueue |
5 | 5 |
|
6 | 6 | from . import cubes |
7 | 7 |
|
@@ -140,97 +140,61 @@ def astar(app_scene, cube, paths): # Thread |
140 | 140 | return False, len(visited), 0, 0 |
141 | 141 |
|
142 | 142 |
|
143 | | -def dfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList) -> bool: |
144 | | - """Finds a path from the starting node to the end node. |
145 | | -
|
146 | | - The start node is defined by the current cube's position and the |
147 | | - end node is defined by the pathcube which its is_objective attribute is true. |
148 | | -
|
149 | | - The algorithm finds a path using the depth-first search algorithm. |
150 | | -
|
151 | | - Returns: |
152 | | - True if the a path was found, othewise False. |
153 | | - """ |
| 143 | +def _search(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList, container_class): |
| 144 | + """General function for searching.""" |
| 145 | + start_node = paths.find_path(cube) |
| 146 | + came_from = {} |
154 | 147 |
|
| 148 | + queue = container_class() |
155 | 149 | visited = set() |
| 150 | + queue.put(start_node) |
156 | 151 |
|
157 | | - start = paths.find_path(cube) |
158 | | - path = [start] |
159 | | - # stack item: pathcube path |
160 | | - stack = [(start, path)] |
| 152 | + start_node.rect_colour = (255, 0, 255) |
| 153 | + |
| 154 | + while not queue.empty(): |
| 155 | + current_node = queue.get() |
161 | 156 |
|
162 | | - while stack: |
163 | 157 | if not app_scene.traversing: |
164 | 158 | break |
165 | 159 |
|
166 | | - c_pathcube, c_path = stack.pop() |
167 | | - |
168 | | - if c_pathcube in visited: |
| 160 | + if current_node.is_objective: |
| 161 | + path = reconstruct_path(came_from, current_node) |
| 162 | + return (walk(app_scene, cube, path), len(visited), len(path), |
| 163 | + sum(map(lambda p: p.weight, path))) |
| 164 | + elif current_node in visited: |
169 | 165 | continue |
170 | | - if c_pathcube.is_objective: |
171 | | - # A path was found. Animate it |
172 | | - return (walk(app_scene, cube, c_path), len(visited), len(c_path), |
173 | | - sum(map(lambda p: p.weight, c_path))) |
174 | | - |
175 | | - for neighbour in paths.get_neighbors(c_pathcube): |
176 | | - if not neighbour.is_blocked: |
177 | | - next_path = c_path + [neighbour] |
178 | | - stack.append((neighbour, next_path)) |
| 166 | + |
| 167 | + for neighbour in paths.get_neighbors(current_node): |
| 168 | + if not (neighbour.is_blocked or neighbour in visited): |
| 169 | + queue.put(neighbour) |
| 170 | + came_from[neighbour] = current_node |
179 | 171 | neighbour.rect_color = (180, 0, 0) |
180 | | - |
181 | | - c_pathcube.rect_color = (255, 0, 255) |
182 | | - visited.add(c_pathcube) |
183 | | - time.sleep(TIME_INTERVAL) |
184 | 172 |
|
| 173 | + visited.add(current_node) |
| 174 | + current_node.rect_color = (255, 0, 255) |
| 175 | + time.sleep(TIME_INTERVAL) |
185 | 176 | return False, len(visited), 0, 0 |
186 | 177 |
|
187 | 178 |
|
188 | | -def bfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList) -> bool: |
| 179 | +def dfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList) -> bool: |
189 | 180 | """Finds a path from the starting node to the end node. |
190 | 181 |
|
191 | 182 | The start node is defined by the current cube's position and the |
192 | 183 | end node is defined by the pathcube which its is_objective attribute is true. |
193 | 184 |
|
194 | | - The algorithm finds a path using the breadth-first search algorithm. |
| 185 | + The algorithm finds a path using the depth-first search algorithm. |
195 | 186 |
|
196 | 187 | Returns: |
197 | 188 | True if the a path was found, othewise False. |
198 | 189 | """ |
199 | 190 |
|
200 | | - visited = set() |
| 191 | + return _search(app_scene, cube, paths, LifoQueue) |
201 | 192 |
|
202 | | - start = paths.find_path(cube) |
203 | | - path = [start] |
204 | | - # stack item: pathcube path |
205 | | - stack = [(start, path)] |
206 | 193 |
|
207 | | - while stack: |
208 | | - if not app_scene.traversing: |
209 | | - break |
210 | | - |
211 | | - c_pathcube, c_path = stack.pop(0) |
| 194 | +def bfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList): |
| 195 | + """Breadth-first search algorithm.""" |
212 | 196 |
|
213 | | - if c_pathcube in visited: |
214 | | - continue |
215 | | - else: |
216 | | - visited.add(c_pathcube) |
217 | | - |
218 | | - if c_pathcube.is_objective: |
219 | | - # A path was found. Animate it |
220 | | - return (walk(app_scene, cube, c_path), len(visited), len(c_path), |
221 | | - sum(map(lambda p: p.weight, c_path))) |
222 | | - |
223 | | - for neighbour in paths.get_neighbors(c_pathcube): |
224 | | - if not neighbour.is_blocked: |
225 | | - next_path = c_path + [neighbour] |
226 | | - stack.append((neighbour, next_path)) |
227 | | - neighbour.rect_color = (180, 0, 0) |
228 | | - |
229 | | - c_pathcube.rect_color = (255, 0, 255) |
230 | | - |
231 | | - time.sleep(TIME_INTERVAL) |
232 | | - |
233 | | - return False, len(visited), 0, 0 |
| 197 | + return _search(app_scene, cube, paths, Queue) |
234 | 198 |
|
235 | 199 |
|
236 | 200 | def dijkstra(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList): |
|
0 commit comments