Skip to content

Commit c9c4dd2

Browse files
committed
Method improvements and fixes for out of range mouse clicks
1 parent 2d0c492 commit c9c4dd2

File tree

2 files changed

+67
-49
lines changed

2 files changed

+67
-49
lines changed

Metro/Metro_RP2350_Minesweeper/code.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ def hide_group(group):
266266

267267
if left_button and right_button and not chord_selected:
268268
chord_coords = ((mouse_tg.x - ms_board.x) // 16, (mouse_tg.y - ms_board.y) // 16)
269-
chord_selected = True
270-
game_logic.square_chord_highlight(chord_coords)
271-
waiting_for_release = True
269+
chord_selected = game_logic.square_chord_highlight(chord_coords)
270+
if chord_selected:
271+
waiting_for_release = True
272272

273273
if (ms_board.x <= mouse_tg.x <= ms_board.x + game_logic.grid_width * 16 and
274274
ms_board.y <= mouse_tg.y <= ms_board.y + game_logic.grid_height * 16 and

Metro/Metro_RP2350_Minesweeper/gamelogic.py

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)