-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmaze.py
99 lines (81 loc) · 3.25 KB
/
maze.py
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
# Related blog post - https://algoritmim.co.il/2019/06/18/maze-path/
class MazeCell(object):
def __init__(self, i, j, is_wall=False, is_exit=False):
self.i = i
self.j = j
self.visited = False
self.is_wall = is_wall
self.is_exit = is_exit
def __eq__(self, other):
return self.i == other.i and self.j == other.j
def __repr__(self):
repr = "%d,%d" % (self.i, self.j)
if self.visited:
repr += ',visited'
if self.is_exit:
repr += ' (EXIT)'
return repr
class Maze(object):
def __init__(self, maze_matrix):
self.maze = maze_matrix
self.cells_cache = {}
self.rows = len(maze_matrix)
self.columns = len(maze_matrix[0])
def find_path_to_exit_in_maze(self, start_cell):
path = [start_cell]
while len(path) > 0:
current_cell = path[-1]
current_cell.visited = True
adjacent_cell = self.get_available_adjacent_cell(current_cell)
if adjacent_cell is None:
path.pop()
else:
path.append(adjacent_cell)
if adjacent_cell.is_exit:
return path
return -1
def get_cell(self, i, j):
if (i,j) not in self.cells_cache:
self.cells_cache[(i,j)] = MazeCell(i, j, self.maze[i][j] == 1, self.maze[i][j] == "EXIT")
return self.cells_cache[(i,j)]
def get_available_adjacent_cell(self, cell):
for (i, j) in [(cell.i - 1, cell.j), (cell.i, cell.j - 1), (cell.i + 1, cell.j), (cell.i, cell.j + 1)]:
if 0 <= i < self.rows and 0 <= j < self.columns:
adj = self.get_cell(i,j)
if adj.visited or adj.is_wall:
continue
else:
return adj
return None
def run_tests():
maze_matrix = [[1, "ENTERANEC", 1, 1],
[1, 0, 0, 1],
[1, 0, 1, 1],
[1, 0, 0, 1],
[1, 1, "EXIT", 1]]
maze = Maze(maze_matrix)
expected_path = [MazeCell(0, 1), MazeCell(1, 1), MazeCell(2, 1), MazeCell(3, 1), MazeCell(3, 2),
MazeCell(4, 2, is_exit=True)]
assert maze.find_path_to_exit_in_maze(MazeCell(0, 1)) == expected_path
maze_matrix = [[1, "ENTERANEC", 1, 1],
[1, 0, 0, 1],
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 1, "EXIT", 1]]
maze = Maze(maze_matrix)
assert maze.find_path_to_exit_in_maze(MazeCell(0, 1)) == -1
maze_matrix = [[1, "ENTERANEC", 1, 1],
[1, 1, "EXIT", 1]]
maze = Maze(maze_matrix)
assert maze.find_path_to_exit_in_maze(MazeCell(0, 1)) == -1
maze_matrix = [[1, "ENTERANEC", 1, 1],
[1, "EXIT", 1, 1]]
maze = Maze(maze_matrix)
expected_path = [MazeCell(0, 1), MazeCell(1, 1, is_exit=True)]
assert maze.find_path_to_exit_in_maze(MazeCell(0, 1)) == expected_path
maze_matrix = [["ENTERANEC", 0, 0, "EXIT"]]
maze = Maze(maze_matrix)
expected_path = [MazeCell(0, 0), MazeCell(0, 1), MazeCell(0, 2), MazeCell(0,3, is_exit=True)]
assert maze.find_path_to_exit_in_maze(MazeCell(0, 0)) == expected_path
if __name__ == '__main__':
run_tests()