Skip to content

Commit 77710f4

Browse files
committed
memory game files inital commit
1 parent 05ca129 commit 77710f4

File tree

11 files changed

+802
-0
lines changed

11 files changed

+802
-0
lines changed
922 Bytes
Binary file not shown.
922 Bytes
Binary file not shown.

Metro/Metro_RP2350_Memory/memory_game/code.py

Lines changed: 478 additions & 0 deletions
Large diffs are not rendered by default.
20.2 KB
Binary file not shown.
76.1 KB
Binary file not shown.
198 Bytes
Binary file not shown.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
"""
4+
This example is made for a basic Microsoft optical mouse with
5+
two buttons and a wheel that can be pressed.
6+
7+
It assumes there is a single mouse connected to USB Host,
8+
and no other devices connected.
9+
"""
10+
import array
11+
from displayio import Group, OnDiskBitmap, TileGrid
12+
from adafruit_display_text.bitmap_label import Label
13+
import supervisor
14+
import terminalio
15+
import usb.core
16+
17+
# use the built-in HSTX display for Metro RP2350
18+
display = supervisor.runtime.display
19+
20+
# group to hold visual elements
21+
main_group = Group()
22+
23+
# make the group visible on the display
24+
display.root_group = main_group
25+
26+
# load the mouse cursor bitmap
27+
mouse_bmp = OnDiskBitmap("mouse_cursor.bmp")
28+
29+
# make the background pink pixels transparent
30+
mouse_bmp.pixel_shader.make_transparent(0)
31+
32+
# create a TileGrid for the mouse, using its bitmap and pixel_shader
33+
mouse_tg = TileGrid(mouse_bmp, pixel_shader=mouse_bmp.pixel_shader)
34+
35+
# move it to the center of the display
36+
mouse_tg.x = display.width // 2
37+
mouse_tg.y = display.height // 2
38+
39+
# text label to show the x, y coordinates on the screen
40+
output_lbl = Label(
41+
terminalio.FONT, text=f"{mouse_tg.x},{mouse_tg.y}", color=0xFFFFFF, scale=1
42+
)
43+
44+
# move it to the upper left corner
45+
output_lbl.anchor_point = (0, 0)
46+
output_lbl.anchored_position = (1, 1)
47+
48+
# add it to the main group
49+
main_group.append(output_lbl)
50+
51+
# add the mouse tile grid to the main group
52+
main_group.append(mouse_tg)
53+
54+
# button names
55+
# This is ordered by bit position.
56+
BUTTONS = ["left", "right", "middle"]
57+
58+
# scan for connected USB device and loop over any found
59+
for device in usb.core.find(find_all=True):
60+
# print device info
61+
print(f"{device.idVendor:04x}:{device.idProduct:04x}")
62+
print(device.manufacturer, device.product)
63+
print(device.serial_number)
64+
# assume the device is the mouse
65+
mouse = device
66+
67+
# detach the kernel driver if needed
68+
if mouse.is_kernel_driver_active(0):
69+
mouse.detach_kernel_driver(0)
70+
71+
# set configuration on the mouse so we can use it
72+
mouse.set_configuration()
73+
74+
# buffer to hold mouse data
75+
# Boot mice have 4 byte reports
76+
buf = array.array("b", [0] * 4)
77+
78+
# main loop
79+
while True:
80+
try:
81+
# attempt to read data from the mouse
82+
# 10ms timeout, so we don't block long if there
83+
# is no data
84+
count = mouse.read(0x81, buf, timeout=10)
85+
except usb.core.USBTimeoutError:
86+
# skip the rest of the loop if there is no data
87+
continue
88+
89+
# update the mouse tilegrid x and y coordinates
90+
# based on the delta values read from the mouse
91+
mouse_tg.x = max(0, min(display.width - 1, mouse_tg.x + buf[1]))
92+
mouse_tg.y = max(0, min(display.height - 1, mouse_tg.y + buf[2]))
93+
94+
# string with updated coordinates for the text label
95+
out_str = f"{mouse_tg.x},{mouse_tg.y}"
96+
97+
# loop over the button names
98+
for i, button in enumerate(BUTTONS):
99+
# check if each button is pressed using bitwise AND shifted
100+
# to the appropriate index for this button
101+
if buf[0] & (1 << i) != 0:
102+
# append the button name to the string to show if
103+
# it is being clicked.
104+
out_str += f" {button}"
105+
106+
# update the text label with the new coordinates
107+
# and buttons being pressed
108+
output_lbl.text = out_str
198 Bytes
Binary file not shown.
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
"""
4+
This example is made for a basic Microsoft optical mouse with
5+
two buttons and a wheel that can be pressed.
6+
7+
It assumes there is a single mouse connected to USB Host,
8+
and no other devices connected.
9+
10+
It illustrates multi-player turn based logic with a very
11+
basic implementation of tic-tac-toe.
12+
"""
13+
import array
14+
import random
15+
from displayio import Group, OnDiskBitmap, TileGrid
16+
from adafruit_display_text.bitmap_label import Label
17+
from adafruit_displayio_layout.layouts.grid_layout import GridLayout
18+
import supervisor
19+
import terminalio
20+
import usb.core
21+
# use the built-in HSTX display for Metro RP2350
22+
display = supervisor.runtime.display
23+
24+
# group to hold visual elements
25+
main_group = Group()
26+
27+
# make the group visible on the display
28+
display.root_group = main_group
29+
30+
# load the mouse cursor bitmap
31+
mouse_bmp = OnDiskBitmap("mouse_cursor.bmp")
32+
33+
# make the background pink pixels transparent
34+
mouse_bmp.pixel_shader.make_transparent(0)
35+
36+
# create a TileGrid for the mouse, using its bitmap and pixel_shader
37+
mouse_tg = TileGrid(mouse_bmp, pixel_shader=mouse_bmp.pixel_shader)
38+
39+
# move it to the center of the display
40+
mouse_tg.x = display.width // 2
41+
mouse_tg.y = display.height // 2
42+
43+
# text label to show the x, y coordinates on the screen
44+
output_lbl = Label(terminalio.FONT, text="", color=0xFFFFFF, scale=1)
45+
46+
# move it to the right side of the screen
47+
output_lbl.anchor_point = (0, 0)
48+
output_lbl.anchored_position = (180, 40)
49+
50+
# add it to the main group
51+
main_group.append(output_lbl)
52+
53+
# scan for connected USB device and loop over any found
54+
for device in usb.core.find(find_all=True):
55+
# print device info
56+
print(f"{device.idVendor:04x}:{device.idProduct:04x}")
57+
print(device.manufacturer, device.product)
58+
print(device.serial_number)
59+
# assume the device is the mouse
60+
mouse = device
61+
62+
# detach the kernel driver if needed
63+
if mouse.is_kernel_driver_active(0):
64+
mouse.detach_kernel_driver(0)
65+
66+
# set configuration on the mouse so we can use it
67+
mouse.set_configuration()
68+
69+
# buffer to hold mouse data
70+
# Boot mice have 4 byte reports
71+
buf = array.array("b", [0] * 4)
72+
73+
# set up a 3x3 grid for the tic-tac-toe board
74+
board_grid = GridLayout(
75+
x=40,
76+
y=40,
77+
width=128,
78+
height=128,
79+
grid_size=(3, 3)
80+
)
81+
82+
# load the tic-tac-toe spritesheet
83+
tictactoe_spritesheet = OnDiskBitmap("tictactoe_spritesheet.bmp")
84+
85+
# X is index 1 in the spritesheet, O is index 2 in the spritesheet
86+
player_icon_indexes = [1, 2]
87+
88+
# current player variable.
89+
# When this equlas 0 its X's turn,
90+
# when it equals 1 it is O's turn.
91+
current_player_index = random.randint(0, 1) # randomize the initial player
92+
93+
# loop over rows
94+
for y in range(3):
95+
# loop over columns
96+
for x in range(3):
97+
# create a TileGrid for this cell
98+
new_tg = TileGrid(bitmap=tictactoe_spritesheet, default_tile=0,
99+
tile_height=32, tile_width=32,
100+
height=1, width=1,
101+
pixel_shader=tictactoe_spritesheet.pixel_shader)
102+
103+
# add the new TileGrid to the board grid at the current position
104+
board_grid.add_content(new_tg, grid_position=(x, y), cell_size=(1, 1))
105+
106+
# add the board grid to the main group
107+
main_group.append(board_grid)
108+
109+
# add the mouse tile grid to the main group
110+
main_group.append(mouse_tg)
111+
112+
113+
def check_for_winner():
114+
"""
115+
check if a player has won
116+
117+
:return: the player icon index of the winning player,
118+
None if no winner and game continues, -1 if game ended in a tie.
119+
"""
120+
found_empty = False
121+
122+
# check rows
123+
for row_idx in range(3):
124+
# if the 3 cells in this row match
125+
if (board_grid[0 + (row_idx * 3)][0] != 0 and
126+
board_grid[0 + (row_idx * 3)][0] ==
127+
board_grid[1 + (row_idx * 3)][0] ==
128+
board_grid[2 + (row_idx * 3)][0]):
129+
return board_grid[0 + (row_idx * 3)][0]
130+
131+
# if any of the cells in this row are empty
132+
if 0 in (board_grid[0 + (row_idx * 3)][0],
133+
board_grid[1 + (row_idx * 3)][0],
134+
board_grid[2 + (row_idx * 3)][0]):
135+
found_empty = True
136+
137+
# check columns
138+
for col_idx in range(3):
139+
# if the 3 cells in this column match
140+
if (board_grid[0 + col_idx][0] != 0 and
141+
board_grid[0 + col_idx][0] ==
142+
board_grid[3 + col_idx][0] ==
143+
board_grid[6 + col_idx][0]):
144+
return board_grid[0 + col_idx][0]
145+
146+
# if any of the cells in this column are empty
147+
if 0 in (board_grid[0 + col_idx][0],
148+
board_grid[3 + col_idx][0],
149+
board_grid[6 + col_idx][0]):
150+
found_empty = True
151+
152+
# check diagonals
153+
if board_grid[0][0] != 0 and \
154+
board_grid[0][0] == board_grid[4][0] == board_grid[8][0]:
155+
return board_grid[0][0]
156+
157+
if board_grid[2][0] != 0 and \
158+
board_grid[2][0] == board_grid[4][0] == board_grid[6][0]:
159+
return board_grid[2][0]
160+
161+
if found_empty:
162+
# return None if there is no winner and the game continues
163+
return None
164+
else:
165+
# return -1 if it's a tie game with no winner
166+
return -1
167+
168+
169+
# main loop
170+
while True:
171+
try:
172+
# attempt to read data from the mouse
173+
# 10ms timeout, so we don't block long if there
174+
# is no data
175+
count = mouse.read(0x81, buf, timeout=10)
176+
except usb.core.USBTimeoutError:
177+
# skip the rest of the loop if there is no data
178+
continue
179+
180+
# update the mouse tilegrid x and y coordinates
181+
# based on the delta values read from the mouse
182+
mouse_tg.x = max(0, min(display.width - 1, mouse_tg.x + buf[1]))
183+
mouse_tg.y = max(0, min(display.height - 1, mouse_tg.y + buf[2]))
184+
185+
# if left button clicked
186+
if buf[0] & (1 << 0) != 0:
187+
# get the mouse pointer coordinates accounting for the offset of
188+
# the board grid location
189+
coords = (mouse_tg.x - board_grid.x, mouse_tg.y - board_grid.y, 0)
190+
191+
# loop over all cells in the board
192+
for cell_tg in board_grid:
193+
194+
# if the current cell is blank, and contains the clicked coordinates
195+
if cell_tg[0] == 0 and cell_tg.contains(coords):
196+
# set the current cell tile index to the current player's icon
197+
cell_tg[0] = player_icon_indexes[current_player_index]
198+
199+
# change to the next player
200+
current_player_index = (current_player_index + 1) % 2
201+
202+
# print out which player's turn it is
203+
print(f"It is now {'X' if current_player_index == 0 else 'O'}'s turn")
204+
205+
# check for a winner
206+
result = check_for_winner()
207+
208+
# if Xs or Os have won
209+
if result == 1:
210+
output_lbl.text = "X is the winner!"
211+
elif result == 2:
212+
output_lbl.text = "O is the winner!"
213+
214+
# if it was a tie game
215+
elif result == -1:
216+
output_lbl.text = "Tie game, no winner."
198 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)