@@ -92,24 +92,21 @@ def _set_data(self, x, y, value):
9292 self ._board_data [y * self .grid_width + x ] = value
9393
9494 def _get_data (self , x , y ):
95+ if x < 0 or x >= self .grid_width or y < 0 or y >= self .grid_height :
96+ return None # out of bounds, do nothing
9597 return self ._board_data [y * self .grid_width + x ]
9698
9799 def _set_board (self , x , y , value ):
98100 if not isinstance (self .game_board , TileGrid ):
99101 raise ValueError ("Game board not initialized" )
100102 self .game_board [x , y ] = value # pylint: disable=unsupported-assignment-operation
101103
102- def _get_board (self , x , y , dx = 0 , dy = 0 ):
104+ def _get_board (self , x , y ):
103105 if not isinstance (self .game_board , TileGrid ):
104106 raise ValueError ("Game board not initialized" )
105-
106- if x + dx < 0 or x + dx >= self .grid_width :
107- return None # Off screen
108-
109- if y + dy < 0 or y + dy >= self .grid_height :
110- return None # Off screen
111-
112- return self .game_board [x + dx , y + dy ] # pylint: disable=unsubscriptable-object
107+ if x < 0 or x >= self .grid_width or y < 0 or y >= self .grid_height :
108+ return None # out of bounds, do nothing
109+ return self .game_board [x , y ] # pylint: disable=unsubscriptable-object
113110
114111 def _compute_counts (self ):
115112 """For each mine, increment the count in each non-mine square around it"""
@@ -173,53 +170,74 @@ def square_flagged(self, coords):
173170 return True
174171
175172 def square_chorded (self , coords ):
176- # pylint: disable=too-many-nested-blocks
177173 if self ._status in (STATUS_WON , STATUS_LOST ):
178174 return False
179175
180176 x , y = coords
181- if self ._get_board (x , y ) in (OPEN1 , OPEN2 , OPEN3 , OPEN4 , OPEN5 , OPEN6 , OPEN7 , OPEN8 ):
182- # Count the flags around this square
183- flags = 0
184- for dx in (- 1 , 0 , 1 ):
185- for dy in (- 1 , 0 , 1 ):
186- if dx == 0 and dy == 0 :
187- continue # don't process where the mine
188- if self ._get_board (x , y , dx , dy ) == FLAG :
189- flags += 1
190- if flags == self ._get_board (x , y ):
191- # Uncover all non-flagged squares around here
192- for dx in (- 1 , 0 , 1 ):
193- for dy in (- 1 , 0 , 1 ):
194- if dx == 0 and dy == 0 :
195- continue # don't process where the mine
196- _tile_content = self ._get_board (x , y , dx , dy )
197- if _tile_content not in (FLAG , None ):
198- if not self .square_clicked ((x + dx , y + dy )):
199- return False # lost
177+ if x < 0 or x >= self .grid_width or y < 0 or y >= self .grid_height :
178+ return True # out of bounds, do nothing
179+
180+ value = self ._get_board (x , y )
181+
182+ if value not in (OPEN1 , OPEN2 , OPEN3 , OPEN4 , OPEN5 , OPEN6 , OPEN7 , OPEN8 ):
183+ return True # Nothing to do if not an open numbered square
184+
185+ # Pre-compute valid neighbors
186+ neighbors = [
187+ (nx , ny )
188+ for nx in range (x - 1 , x + 2 )
189+ for ny in range (y - 1 , y + 2 )
190+ if (0 <= nx < self .grid_width
191+ and 0 <= ny < self .grid_height
192+ and not (nx == x and ny == y ))
193+ ]
194+
195+ # Count flagged neighbors
196+ flags = sum (1 for nx , ny in neighbors if self ._get_board (nx , ny ) == FLAG )
197+
198+ if flags != value :
199+ return True # not enough flags, do nothing
200+
201+ # Uncover all non-flagged neighbors
202+ for nx , ny in neighbors :
203+ if self ._get_board (nx , ny ) != FLAG :
204+ if not self .square_clicked ((nx , ny )):
205+ return False # lost
206+
200207 return True
201208
202209 def square_chord_highlight (self , coords , highlight = True ):
203210 if self ._status in (STATUS_WON , STATUS_LOST ):
204211 return False
205212
206213 x , y = coords
207- if self ._get_board (x , y ) in (OPEN1 , OPEN2 , OPEN3 , OPEN4 , OPEN5 , OPEN6 , OPEN7 , OPEN8 ):
208- # Highlight all non-flagged squares around here
209- for dx in (- 1 , 0 , 1 ):
210- if x + dx < 0 or x + dx >= self .grid_width :
211- continue # off screen
212- for dy in (- 1 , 0 , 1 ):
213- if y + dy < 0 or y + dy >= self .grid_height :
214- continue # off screen
215- if dx == 0 and dy == 0 :
216- continue # don't process where the mine
217- if highlight :
218- if self ._get_board (x + dx , y + dy ) == BLANK :
219- self ._set_board (x + dx , y + dy ,MINE_QUESTION_OPEN )
220- else :
221- if self ._get_board (x + dx , y + dy ) == MINE_QUESTION_OPEN :
222- self ._set_board (x + dx , y + dy , BLANK )
214+ if x < 0 or x >= self .grid_width or y < 0 or y >= self .grid_height :
215+ return False # out of bounds, do nothing
216+
217+ value = self ._get_board (x , y )
218+
219+ if value not in (OPEN1 , OPEN2 , OPEN3 , OPEN4 , OPEN5 , OPEN6 , OPEN7 , OPEN8 ):
220+ return False # Nothing to do if not an open numbered square
221+
222+ # Pre-compute valid neighbors
223+ neighbors = [
224+ (nx , ny )
225+ for nx in range (x - 1 , x + 2 )
226+ for ny in range (y - 1 , y + 2 )
227+ if (0 <= nx < self .grid_width
228+ and 0 <= ny < self .grid_height
229+ and not (nx == x and ny == y ))
230+ ]
231+
232+ # Highlight all non-flagged squares around here
233+ for nx , ny in neighbors :
234+ if highlight :
235+ if self ._get_board (nx , ny ) == BLANK :
236+ self ._set_board (nx , ny ,MINE_QUESTION_OPEN )
237+ else :
238+ if self ._get_board (nx , ny ) == MINE_QUESTION_OPEN :
239+ self ._set_board (nx , ny , BLANK )
240+
223241 return True
224242
225243 def square_clicked (self , coords ):
@@ -235,7 +253,7 @@ def square_clicked(self, coords):
235253 if self ._start_time is None :
236254 self ._start_time = ticks_ms ()
237255
238- if self ._get_board (x , y ) != FLAG :
256+ if self ._get_board (x , y ) not in ( FLAG , None ) :
239257 under_the_tile = self ._get_data (x , y )
240258 if under_the_tile == MINE :
241259 self ._set_data (x , y , MINE_CLICKED )
0 commit comments