Skip to content

Commit a9bf70a

Browse files
maze traversal visual using BFS
1 parent a71618f commit a9bf70a

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

searches/maze_traversal_BFS.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# MAZE TRAVERSAL
2+
3+
import curses
4+
from curses import wrapper
5+
import queue
6+
import time
7+
import sys
8+
9+
# maze = [
10+
# ["#", "O", "#", "#", "#", "#", "#", "#", "#"],
11+
# ["#", " ", " ", " ", " ", " ", " ", " ", "#"],
12+
# ["#", " ", "#", "#", " ", "#", "#", " ", "#"],
13+
# ["#", " ", "#", " ", " ", " ", "#", " ", "#"],
14+
# ["#", " ", "#", " ", "#", " ", "#", " ", "#"],
15+
# ["#", " ", "#", " ", "#", " ", "#", " ", "#"],
16+
# ["#", " ", "#", " ", "#", " ", "#", "#", "#"],
17+
# ["#", " ", " ", " ", " ", " ", " ", " ", "#"],
18+
# ["#", "#", "#", "#", "#", "#", "#", "X", "#"]
19+
# ]
20+
21+
maze = [
22+
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
23+
["#", "O", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
24+
["#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", " ", "#"],
25+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
26+
["#", " ", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", " ", "#"],
27+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
28+
["#", " ", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", "#"],
29+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
30+
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", "#", "#", " ", "#"],
31+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
32+
["#", " ", "#", "#", "#", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", "#", "#", "#", "#"],
33+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
34+
["#", " ", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", " ", "#"],
35+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
36+
["#", "#", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", "#", "#"],
37+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
38+
["#", " ", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", " ", "#"],
39+
["#", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "#"],
40+
["#", " ", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "X", "#"],
41+
["#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#", "#"]
42+
]
43+
44+
def print_maze(maze, stdscr, visited, path=[]):
45+
blue = curses.color_pair(1)
46+
red = curses.color_pair(2)
47+
green = curses.color_pair(3)
48+
49+
for row, i in enumerate(maze):
50+
for column, j in enumerate(i):
51+
if (row, column) in path:
52+
stdscr.addstr(row, column*2, "X", green)
53+
elif (row, column) in visited:
54+
stdscr.addstr(row, column*2, "X", red)
55+
else:
56+
stdscr.addstr(row, column*2, j, blue)
57+
58+
59+
def find(maze, start): #to check and return starting position in maze
60+
for row, i in enumerate(maze):
61+
for column, j in enumerate(i):
62+
if j == start:
63+
return (row,column) # return tuple of row, column location of element in the maze
64+
return None
65+
66+
def find_neighbours(maze, row, col): #search and return each neighbour of a particular cell, without checking if its a wall or not
67+
neighbours = []
68+
69+
if row > 0: # for UP
70+
neighbours.append((row-1, col))
71+
if row + 1< len(maze): # for DOWN
72+
neighbours.append((row+1, col))
73+
if col + 1 < len(maze[0]): # for RIGHT
74+
neighbours.append((row, col + 1))
75+
if col > 0: # for LEFT
76+
neighbours.append((row, col - 1))
77+
return neighbours
78+
79+
80+
def traverse(maze, stdscr): #implementing bfs traversal
81+
start = "O"
82+
target = "X"
83+
start_pos = find(maze, start)
84+
85+
if start_pos == None:
86+
sys.exit("Starting position not found!")
87+
88+
q = queue.Queue() #initialise queue
89+
q.put((start_pos, [start_pos])) #put each position as well as path as a tuple
90+
91+
visited = set()
92+
93+
while not q.empty():
94+
current_pos, path = q.get()
95+
row, col = current_pos
96+
97+
stdscr.clear()
98+
print_maze(maze, stdscr, visited, path)
99+
# time.sleep(0.1)
100+
stdscr.refresh()
101+
102+
if maze[row][col] == target:
103+
return path
104+
105+
neighbours = find_neighbours(maze, row, col)
106+
for nbr in neighbours:
107+
if nbr in visited:
108+
continue
109+
110+
r, c = nbr
111+
if maze[r][c] == "#":
112+
continue
113+
114+
new_path = path + [nbr]
115+
q.put((nbr, new_path))
116+
visited.add(nbr)
117+
118+
119+
def main(stdscr):
120+
curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK)
121+
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
122+
curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)
123+
124+
traverse(maze, stdscr)
125+
126+
stdscr.getch()
127+
128+
# wrapper(main)
129+
130+
131+
if __name__ == '__main__':
132+
wrapper(main)

0 commit comments

Comments
 (0)