@@ -5,9 +5,13 @@ def __init__(self, x, y, reachable):
5
5
"""
6
6
Initialize new cell
7
7
8
+ @param reachable is cell reachable? not a wall?
8
9
@param x cell x coordinate
9
10
@param y cell y coordinate
10
- @param reachable is cell reachable? not a wall?
11
+ @param g cost to move from the starting cell to this cell.
12
+ @param h estimation of the cost to move from this cell
13
+ to the ending cell.
14
+ @param f f = g + h
11
15
"""
12
16
self .reachable = reachable
13
17
self .x = x
@@ -19,32 +23,43 @@ def __init__(self, x, y, reachable):
19
23
20
24
class AStar (object ):
21
25
def __init__ (self ):
26
+ # open list
22
27
self .opened = []
23
28
heapq .heapify (self .opened )
29
+ # visited cells list
24
30
self .closed = set ()
31
+ # grid cells
25
32
self .cells = []
26
- self .grid_height = 6
27
- self .grid_width = 6
33
+ self .grid_height = None
34
+ self .grid_width = None
28
35
29
- def init_grid (self ):
30
- walls = ((0 , 5 ), (1 , 0 ), (1 , 1 ), (1 , 5 ), (2 , 3 ),
31
- (3 , 1 ), (3 , 2 ), (3 , 5 ), (4 , 1 ), (4 , 4 ), (5 , 1 ))
36
+ def init_grid (self , width , height , walls , start , end ):
37
+ """
38
+ Prepare grid cells, walls.
39
+
40
+ @param width grid's width.
41
+ @param height grid's height.
42
+ @param walls list of wall x,y tuples.
43
+ @param start grid starting point x,y tuple.
44
+ @param end grid ending point x,y tuple.
45
+ """
46
+ self .grid_height = height
47
+ self .grid_width = width
32
48
for x in range (self .grid_width ):
33
49
for y in range (self .grid_height ):
34
50
if (x , y ) in walls :
35
51
reachable = False
36
52
else :
37
53
reachable = True
38
54
self .cells .append (Cell (x , y , reachable ))
39
- self .start = self .get_cell (0 , 0 )
40
- self .end = self .get_cell (5 , 5 )
55
+ self .start = self .get_cell (* start )
56
+ self .end = self .get_cell (* end )
41
57
42
58
def get_heuristic (self , cell ):
43
59
"""
44
60
Compute the heuristic value H for a cell: distance between
45
61
this cell and the ending cell multiply by 10.
46
62
47
- @param cell
48
63
@returns heuristic value H
49
64
"""
50
65
return 10 * (abs (cell .x - self .end .x ) + abs (cell .y - self .end .y ))
@@ -65,7 +80,7 @@ def get_adjacent_cells(self, cell):
65
80
from the one on the right.
66
81
67
82
@param cell get adjacent cells for this cell
68
- @returns adjacent cells list
83
+ @returns adjacent cells list.
69
84
"""
70
85
cells = []
71
86
if cell .x < self .grid_width - 1 :
@@ -78,11 +93,16 @@ def get_adjacent_cells(self, cell):
78
93
cells .append (self .get_cell (cell .x , cell .y + 1 ))
79
94
return cells
80
95
81
- def display_path (self ):
96
+ def get_path (self ):
82
97
cell = self .end
98
+ path = [(cell .x , cell .y )]
83
99
while cell .parent is not self .start :
84
100
cell = cell .parent
85
- print 'path: cell: %d,%d' % (cell .x , cell .y )
101
+ path .append ((cell .x , cell .y ))
102
+
103
+ path .append ((self .start .x , self .start .y ))
104
+ path .reverse ()
105
+ return path
86
106
87
107
def compare (self , cell1 , cell2 ):
88
108
"""
@@ -97,7 +117,7 @@ def compare(self, cell1, cell2):
97
117
elif cell1 .f > cell2 .f :
98
118
return 1
99
119
return 0
100
-
120
+
101
121
def update_cell (self , adj , cell ):
102
122
"""
103
123
Update adjacent cell
@@ -110,18 +130,22 @@ def update_cell(self, adj, cell):
110
130
adj .parent = cell
111
131
adj .f = adj .h + adj .g
112
132
113
- def process (self ):
133
+ def solve (self ):
134
+ """
135
+ Solve maze, find path to ending cell.
136
+
137
+ @returns path or None if not found.
138
+ """
114
139
# add starting cell to open heap queue
115
140
heapq .heappush (self .opened , (self .start .f , self .start ))
116
141
while len (self .opened ):
117
- # pop cell from heap queue
142
+ # pop cell from heap queue
118
143
f , cell = heapq .heappop (self .opened )
119
144
# add cell to closed list so we don't process it twice
120
145
self .closed .add (cell )
121
- # if ending cell, display found path
146
+ # if ending cell, return found path
122
147
if cell is self .end :
123
- self .display_path ()
124
- break
148
+ return self .get_path ()
125
149
# get adjacent cells for cell
126
150
adj_cells = self .get_adjacent_cells (cell )
127
151
for adj_cell in adj_cells :
@@ -137,7 +161,4 @@ def process(self):
137
161
# add adj cell to open list
138
162
heapq .heappush (self .opened , (adj_cell .f , adj_cell ))
139
163
140
- a = AStar ()
141
- a .init_grid ()
142
- a .process ()
143
164
0 commit comments