Skip to content

Commit 3911d60

Browse files
committed
update: Extract Breadth-first search and Depth-first search algorithm onto general function _search
1 parent 76a7e61 commit 3911d60

1 file changed

Lines changed: 30 additions & 66 deletions

File tree

src/pathfinding/algorithms.py

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""algorithms.py module"""
22

33
import time
4-
from queue import PriorityQueue
4+
from queue import PriorityQueue, Queue, LifoQueue
55

66
from . import cubes
77

@@ -140,97 +140,61 @@ def astar(app_scene, cube, paths): # Thread
140140
return False, len(visited), 0, 0
141141

142142

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 = {}
154147

148+
queue = container_class()
155149
visited = set()
150+
queue.put(start_node)
156151

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()
161156

162-
while stack:
163157
if not app_scene.traversing:
164158
break
165159

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:
169165
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
179171
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)
184172

173+
visited.add(current_node)
174+
current_node.rect_color = (255, 0, 255)
175+
time.sleep(TIME_INTERVAL)
185176
return False, len(visited), 0, 0
186177

187178

188-
def bfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList) -> bool:
179+
def dfs(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList) -> bool:
189180
"""Finds a path from the starting node to the end node.
190181
191182
The start node is defined by the current cube's position and the
192183
end node is defined by the pathcube which its is_objective attribute is true.
193184
194-
The algorithm finds a path using the breadth-first search algorithm.
185+
The algorithm finds a path using the depth-first search algorithm.
195186
196187
Returns:
197188
True if the a path was found, othewise False.
198189
"""
199190

200-
visited = set()
191+
return _search(app_scene, cube, paths, LifoQueue)
201192

202-
start = paths.find_path(cube)
203-
path = [start]
204-
# stack item: pathcube path
205-
stack = [(start, path)]
206193

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."""
212196

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)
234198

235199

236200
def dijkstra(app_scene, cube: cubes.CharacterCube, paths: cubes.PathCubeList):

0 commit comments

Comments
 (0)