Skip to content

Commit 7a70648

Browse files
committed
Move code into the learning guide repo
1 parent 47b4caf commit 7a70648

1 file changed

Lines changed: 203 additions & 0 deletions

File tree

Minesweep/code.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
"""
2+
PyPortal based countdown of days until Halloween.
3+
4+
Adafruit invests time and resources providing this open source code.
5+
Please support Adafruit and open source hardware by purchasing
6+
products from Adafruit!
7+
8+
Written by Dave Astels for Adafruit Industries
9+
Copyright (c) 2019 Adafruit Industries
10+
Licensed under the MIT license.
11+
12+
All text above must be included in any redistribution.
13+
"""
14+
15+
import time
16+
import board
17+
import displayio
18+
import adafruit_imageload
19+
import adafruit_touchscreen
20+
from random import seed, randint
21+
from adafruit_bitmapsaver import save_pixels
22+
from adafruit_debouncer import Debouncer
23+
24+
seed(int(time.monotonic()))
25+
26+
NUMBER_OF_BOMBS = 15
27+
28+
# Board pieces
29+
30+
OPEN0 = 0
31+
OPEN1 = 1
32+
OPEN2 = 2
33+
OPEN3 = 3
34+
OPEN4 = 4
35+
OPEN5 = 5
36+
OPEN6 = 6
37+
OPEN7 = 7
38+
OPEN8 = 8
39+
BLANK = 9
40+
BOMBDEATH = 10
41+
BOMBFLAGGED = 11
42+
BOMBMISFLAGGED = 12
43+
BOMBQUESTION = 13
44+
BOMBREVEALED = 14
45+
46+
snapshot = Debouncer(board.D4)
47+
48+
sprite_sheet, palette = adafruit_imageload.load("/SpriteSheet.bmp",
49+
bitmap=displayio.Bitmap,
50+
palette=displayio.Palette)
51+
52+
display = board.DISPLAY
53+
group = displayio.Group(scale=1, max_size=5)
54+
touchscreen = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR,
55+
board.TOUCH_YD, board.TOUCH_YU,
56+
calibration=((9000, 59000),
57+
(8000, 57000)),
58+
size=(display.width, display.height))
59+
tilegrid = displayio.TileGrid(sprite_sheet, pixel_shader=palette,
60+
width=20, height=15,
61+
tile_height=16, tile_width=16,
62+
default_tile=BLANK)
63+
group.append(tilegrid)
64+
display.show(group)
65+
66+
DATA_BOMB = -1
67+
68+
board_data = bytearray(b'\x00' * 300)
69+
70+
#pylint:disable=redefined-outer-name
71+
def get_data(x, y):
72+
return board_data[y * 20 + x]
73+
74+
def set_data(x, y, value):
75+
board_data[y * 20 + x] = value
76+
#pylint:disable=redefined-outer-name
77+
78+
79+
def seed_bombs(how_many):
80+
for _ in range(how_many):
81+
while True:
82+
bomb_x = randint(0, 19)
83+
bomb_y = randint(0, 14)
84+
if get_data(bomb_x, bomb_y) == 0:
85+
set_data(bomb_x, bomb_y, 14)
86+
break
87+
88+
89+
def compute_counts():
90+
"""For each bomb, increment the count in each non-bomb square around it"""
91+
for y in range(15):
92+
for x in range(20):
93+
if get_data(x, y) != 14:
94+
continue # keep looking for bombs
95+
print('found bomb at %d, %d' % (x, y))
96+
for dx in (-1, 0, 1):
97+
if x + dx < 0 or x + dx >= 20:
98+
continue # off screen
99+
for dy in (-1, 0, 1):
100+
if y + dy < 0 or y + dy >= 15:
101+
continue # off screen
102+
count = get_data(x + dx, y + dy)
103+
if count == 14:
104+
continue # don't process bombs
105+
set_data(x + dx, y + dy, count + 1)
106+
107+
108+
def reveal():
109+
for x in range(20):
110+
for y in range(15):
111+
tilegrid[x, y] = get_data(x, y)
112+
113+
114+
def expand_uncovered(start_x, start_y):
115+
number_uncovered = 1
116+
stack = [(start_x, start_y)]
117+
while len(stack) > 0:
118+
x, y = stack.pop()
119+
if tilegrid[x, y] == BLANK:
120+
under_the_tile = get_data(x, y)
121+
if under_the_tile <= OPEN8:
122+
tilegrid[x, y] = under_the_tile
123+
number_uncovered += 1
124+
if under_the_tile == OPEN0:
125+
for dx in (-1, 0, 1):
126+
if x + dx < 0 or x + dx >= 20:
127+
continue # off screen
128+
for dy in (-1, 0, 1):
129+
if y + dy < 0 or y + dy >= 15:
130+
continue # off screen
131+
if dx == 0 and dy == 0:
132+
continue # don't process where the bomb
133+
stack.append((x + dx, y + dy))
134+
return number_uncovered
135+
136+
137+
def play_a_game():
138+
number_uncovered = 0
139+
touch_x = -1
140+
touch_y = -1
141+
last_x = -1
142+
last_y = -1
143+
hold_count = 0
144+
press = 0
145+
touch_time = 0
146+
while True:
147+
now = time/monotonic()
148+
snapshot.update()
149+
if snapshot.fell:
150+
save_pixels()
151+
if now >= touch_time:
152+
touch_time = now + 0.1
153+
touch_at = touchscreen.touch_point
154+
if touch_at is not None:
155+
touch_x = max(min([touch_at[0] // 16, 19]), 0)
156+
touch_y = max(min([touch_at[1] // 16, 14]), 0)
157+
if touch_x == last_x and touch_y == last_y:
158+
hold_count += 1
159+
else:
160+
if hold_count > 5:
161+
press = 2
162+
elif hold_count > 1:
163+
elif tilegrid[touch_x, touch_y] == BLANK:
164+
under_the_tile = get_data(touch_x, touch_y)
165+
if under_the_tile == 14:
166+
reveal()
167+
tilegrid[touch_x, touch_y] = BOMBDEATH
168+
time.sleep(10.0)
169+
return False #lost
170+
elif under_the_tile > OPEN0 and under_the_tile <= OPEN8:
171+
tilegrid[touch_x, touch_y] = under_the_tile
172+
elif under_the_tile == OPEN0:
173+
number_uncovered += expand_uncovered(touch_x, touch_y)
174+
else:
175+
print('Unexpected value on board')
176+
return None #something bad happened
177+
continue
178+
if number_uncovered == 300:
179+
return True #won
180+
181+
def reset_board():
182+
for x in range(20):
183+
for y in range(15):
184+
tilegrid[x, y] = BLANK
185+
set_data(x, y, 0)
186+
seed_bombs(NUMBER_OF_BOMBS)
187+
compute_counts()
188+
189+
def play_won_sound():
190+
pass
191+
192+
def play_lost_sound():
193+
pass
194+
195+
while True:
196+
reset_board()
197+
result = play_a_game()
198+
if result is None:
199+
pass
200+
elif result:
201+
play_won_sound()
202+
else:
203+
play_lost_sound()

0 commit comments

Comments
 (0)