Skip to content

Commit a90ff20

Browse files
committed
Minesweeper: add mouse "chording" feature
1 parent fd09a3c commit a90ff20

File tree

2 files changed

+76
-25
lines changed

2 files changed

+76
-25
lines changed

Metro/Metro_RP2350_Minesweeper/code.py

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def update_ui():
123123

124124
buf = array.array("b", [0] * 4)
125125
waiting_for_release = False
126+
chord_selected = False
126127
left_button = right_button = False
127128
mouse_coords = (display.width // 2, display.height // 2)
128129

@@ -231,41 +232,21 @@ def hide_group(group):
231232

232233
menus = (reset_menu, difficulty_menu)
233234

234-
# Mouse state
235-
last_left_button_state = 0
236-
last_right_button_state = 0
237-
left_button_pressed = False
238-
right_button_pressed = False
239-
240235
# main loop
241236
while True:
242237
update_ui()
243238
# update cursor position, and check for clicks
244-
buttons = mouse.update()
239+
mouse.update()
240+
buttons = mouse.pressed_btns
245241

246242
# Extract button states
247-
if buttons is None:
243+
if buttons is None or buttons == ():
248244
left_button = 0
249245
right_button = 0
250246
else:
251247
left_button = 1 if 'left' in buttons else 0
252248
right_button = 1 if 'right' in buttons else 0
253249

254-
# Detect button presses
255-
if left_button == 1 and last_left_button_state == 0:
256-
left_button_pressed = True
257-
elif left_button == 0 and last_left_button_state == 1:
258-
left_button_pressed = False
259-
260-
if right_button == 1 and last_right_button_state == 0:
261-
right_button_pressed = True
262-
elif right_button == 0 and last_right_button_state == 1:
263-
right_button_pressed = False
264-
265-
# Update button states
266-
last_left_button_state = left_button
267-
last_right_button_state = right_button
268-
269250
mouse_coords = (mouse_tg.x, mouse_tg.y)
270251

271252
if waiting_for_release and not left_button and not right_button:
@@ -282,11 +263,23 @@ def hide_group(group):
282263
else:
283264
# process gameboard click if no menu
284265
ms_board = game_logic.game_board
266+
267+
if left_button and right_button and not chord_selected:
268+
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
272+
285273
if (ms_board.x <= mouse_tg.x <= ms_board.x + game_logic.grid_width * 16 and
286274
ms_board.y <= mouse_tg.y <= ms_board.y + game_logic.grid_height * 16 and
287275
not waiting_for_release):
276+
288277
coords = ((mouse_tg.x - ms_board.x) // 16, (mouse_tg.y - ms_board.y) // 16)
289-
if right_button:
278+
if chord_selected:
279+
chord_selected = False
280+
game_logic.square_chord_highlight(chord_coords, False)
281+
game_logic.square_chorded(chord_coords)
282+
elif right_button:
290283
game_logic.square_flagged(coords)
291284
elif left_button:
292285
if not game_logic.square_clicked(coords):

Metro/Metro_RP2350_Minesweeper/gamelogic.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,62 @@ def square_flagged(self, coords):
165165
break
166166
return True
167167

168+
def square_chorded(self, coords):
169+
if self._status in (STATUS_WON, STATUS_LOST):
170+
return False
171+
172+
x, y = coords
173+
if self._get_board(x, y) in (OPEN1, OPEN2, OPEN3, OPEN4, OPEN5, OPEN6, OPEN7, OPEN8):
174+
# Count the flags around this square
175+
flags = 0
176+
for dx in (-1, 0, 1):
177+
if x + dx < 0 or x + dx >= self.grid_width:
178+
continue # off screen
179+
for dy in (-1, 0, 1):
180+
if y + dy < 0 or y + dy >= self.grid_height:
181+
continue # off screen
182+
if dx == 0 and dy == 0:
183+
continue # don't process where the mine
184+
if self._get_board(x + dx, y + dy) == FLAG:
185+
flags += 1
186+
if flags == self._get_board(x, y):
187+
# Uncover all non-flagged squares around here
188+
for dx in (-1, 0, 1):
189+
if x + dx < 0 or x + dx >= self.grid_width:
190+
continue # off screen
191+
for dy in (-1, 0, 1):
192+
if y + dy < 0 or y + dy >= self.grid_height:
193+
continue # off screen
194+
if dx == 0 and dy == 0:
195+
continue # don't process where the mine
196+
if self._get_board(x + dx, y + dy) != FLAG:
197+
if not self.square_clicked((x + dx, y + dy)):
198+
return False # lost
199+
return True
200+
201+
def square_chord_highlight(self, coords, highlight=True):
202+
if self._status in (STATUS_WON, STATUS_LOST):
203+
return False
204+
205+
x, y = coords
206+
if self._get_board(x, y) in (OPEN1, OPEN2, OPEN3, OPEN4, OPEN5, OPEN6, OPEN7, OPEN8):
207+
# Highlight all non-flagged squares around here
208+
for dx in (-1, 0, 1):
209+
if x + dx < 0 or x + dx >= self.grid_width:
210+
continue # off screen
211+
for dy in (-1, 0, 1):
212+
if y + dy < 0 or y + dy >= self.grid_height:
213+
continue # off screen
214+
if dx == 0 and dy == 0:
215+
continue # don't process where the mine
216+
if highlight:
217+
if self._get_board(x + dx, y + dy) == BLANK:
218+
self._set_board(x + dx, y + dy,MINE_QUESTION_OPEN)
219+
else:
220+
if self._get_board(x + dx, y + dy) == MINE_QUESTION_OPEN:
221+
self._set_board(x + dx, y + dy, BLANK)
222+
return True
223+
168224
def square_clicked(self, coords):
169225
x, y = coords
170226

@@ -215,7 +271,9 @@ def check_for_win(self):
215271
# first make sure everything has been explored and decided
216272
for x in range(self.grid_width):
217273
for y in range(self.grid_height):
218-
if self._get_board(x, y) == BLANK or self._get_board(x, y) == MINE_QUESTION:
274+
if self._get_board(x, y) == BLANK or \
275+
self._get_board(x, y) == MINE_QUESTION or \
276+
self._get_board(x, y) == MINE_QUESTION_OPEN:
219277
return None # still ignored or question squares
220278
# then check for mistagged bombs
221279
for x in range(self.grid_width):

0 commit comments

Comments
 (0)