-
Notifications
You must be signed in to change notification settings - Fork 0
/
grid.py
266 lines (199 loc) · 6.55 KB
/
grid.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
"""
This module provides a set of classes for generating and manipulating
a two-dimensional grid of square cells.
Author - Lester Hedges
"""
class Cell:
"""
The class contains functionality for a unit-square cell.
"""
def __init__(self, x, y, w, h):
"""
Construct a specific cell in the grid.
x -- The x position in the grid.
y -- The y position in the grid.
w -- The width of the grid (number of cells).
h -- The height of the grid (number of cells).
"""
if not type(x) is int:
raise TypeError("The x position must be of type 'int'!")
if not type(y) is int:
raise TypeError("The y position must be of type 'int'!")
if not type(w) is int:
raise TypeError("The grid width must be of type 'int'!")
if not type(h) is int:
raise TypeError("The grid height must be of type 'int'!")
if w <= 0:
raise ValueError("The grid width must be greater than zero!")
if h <= 0:
raise ValueError("The grid height must be greater than zero!")
if x < 0 or x >= w:
raise ValueError("The x position must be between 0 and %s!" % (w - 1))
if y < 0 or y >= h:
raise ValueError("The y position must be between 0 and %s!" % (h - 1))
# Set the position of the cell in the grid.
self._x = x
self._y = y
# Flag that the cell is empty.
self._is_occupied = False
# Set the neighbour list.
self._initialiseNeighbours(w, h)
def position(self):
"""
Return the coordinates of the cell as a tuple (x, y).
"""
return (self._x, self._y)
def left(self):
"""
Return the coordinates of the cell to the left as a tuple (x, y).
"""
if self._neighbour_list[0] is None:
return None
else:
return (self._neighbour_list[0], self._y)
def right(self):
"""
Return the coordinates of the cell to right as a tuple (x, y).
"""
if self._neighbour_list[1] is None:
return None
else:
return (self._neighbour_list[1], self._y)
def down(self):
"""
Return the coordinates of the cell below as a tuple (x, y).
"""
if self._neighbour_list[2] is None:
return None
else:
return (self._x, self._neighbour_list[2])
def up(self):
"""
Return the coordinates of the cell above as a tuple (x, y).
"""
if self._neighbour_list[3] is None:
return None
else:
return (self._x, self._neighbour_list[3])
def neighbours(self):
"""
Return the number of neighbouring cells.
"""
return self._neighbours
def occupied(self):
"""
Return whether this cell is occupied.
"""
return self._is_occupied
def fill(self):
"""
Fill the cell.
"""
self._is_occupied = True
def empty(self):
"""
Empty the cell.
"""
self._is_occupied = False
def _initialiseNeighbours(self, w, h):
"""
Initialise the neighbour list.
w -- The width of the grid (number of cells).
h -- The height of the grid (number of cells).
"""
# Initialise the list of neighbouring cells.
self._neighbour_list = [None] * 4
# Initialise the number of neighbouring cells.
self._neighbours = 0
# Cell isn't on left edge.
if self._x > 0:
self._neighbour_list[0] = self._x - 1
self._neighbours += 1
# Cell isn't on right edge.
if self._x < w - 1:
self._neighbour_list[1] = self._x + 1
self._neighbours += 1
# Cell isn't on bottom edge.
if self._y > 0:
self._neighbour_list[2] = self._y - 1
self._neighbours += 1
# Cell isn't on top edge.
if self._y < h - 1:
self._neighbour_list[3] = self._y + 1
self._neighbours += 1
class Grid:
"""
The class contains functionality for a two-dimensional grid of
unit-square cells.
"""
def __init__(self, w, h):
"""
Construct a two-dimensional grid.
w -- The width of the grid (number of cells).
h -- The height of the grid (number of cells).
"""
if not type(w) is int:
raise TypeError("The grid width must be of type 'int'!")
if not type(h) is int:
raise TypeError("The grid height must be of type 'int'!")
if w < 0:
raise ValueError("The width must be positive!")
if h < 0:
raise ValueError("The height must be positive!")
# Set the width of the grid.
self._w = w
# Set the height of the grid.
self._h = h
# Generate a two-dimensional list of cells.
self._cells = [[Cell(x, y, w, h) for y in range(h)] for x in range(w)]
# Initialise an empty list of filled cells.
self._filled = []
def width(self):
"""
Return the width of the grid.
"""
return self._w
def height(self):
"""
Return the height of the grid.
"""
return self._h
def nCells(self):
"""
Return the number of cells in the grid.
"""
return self._w * self._w
def cell(self, x, y):
"""
Get a specific cell from the grid.
x -- The x position of the cell.
y -- The y position of the cell.
"""
return self._cells[x][y]
def nFilled(self):
"""
Return the number of filled cells.
"""
return len(self._filled)
def fill(self, x, y, debug=False):
"""
Fill a cell in the the grid.
x -- The x position of the cell.
y -- The y position of the cell.
"""
# Fill the cell.
self._cells[x][y].fill()
# Add the cell to the 'filled' list.
self._filled.append((x, y))
def empty(self, x, y, debug=False):
"""
Empty a cell in the the grid.
x -- The x position of the cell.
y -- The y position of the cell.
"""
# Make sure the cell is filled.
if self._cells[x][y].occupied():
# Empty the cell.
self._cells[x][y].empty()
# Remove the cell from the filled list.
self._filled.remove((x, y))