from machine import Pin, PWM
import time, random
# -------- Pin map --------
LED_PINS = [2, 3, 4, 5] # 4 LEDs
BTN_PINS = [6, 7, 8, 9] # 4 Buttons (wired to 3V3; PULL_DOWN in code)
BUZZER_PIN = 10 # Passive buzzer (PWM)
SEG_PINS = [11, 12, 13, 14, 15, 16, 17] # 7-seg a..g (common cathode to GND)
# -------- Hardware setup --------
leds = [Pin(p, Pin.OUT, value=0) for p in LED_PINS]
buttons = [Pin(p, Pin.IN, Pin.PULL_DOWN) for p in BTN_PINS]
buzzer = PWM(Pin(BUZZER_PIN))
buzzer.duty_u16(0)
segments = [Pin(p, Pin.OUT, value=0) for p in SEG_PINS]
# 7-seg patterns for common cathode (1 = ON)
DIGITS = {
0:[1,1,1,1,1,1,0],
1:[0,1,1,0,0,0,0],
2:[1,1,0,1,1,0,1],
3:[1,1,1,1,0,0,1],
4:[0,1,1,0,0,1,1],
5:[1,0,1,1,0,1,1],
6:[1,0,1,1,1,1,1],
7:[1,1,1,0,0,0,0],
8:[1,1,1,1,1,1,1],
9:[1,1,1,1,0,1,1],
}
def show_digit(d):
d = 0 if d not in DIGITS else d
pat = DIGITS[d]
for i, pin in enumerate(segments):
pin.value(pat[i])
def beep(freq, dur_s, duty=30000):
buzzer.freq(freq)
buzzer.duty_u16(duty)
time.sleep(dur_s)
buzzer.duty_u16(0)
def flash_led(i, on_ms=220):
leds[i].value(1)
beep(440 + i*120, on_ms/1000)
leds[i].value(0)
time.sleep_ms(70)
def wait_button(timeout_ms=None, debounce_ms=25):
"""Wait for any button press, return index 0..3 or None on timeout."""
start = time.ticks_ms()
while True:
for i, btn in enumerate(buttons):
if btn.value():
time.sleep_ms(debounce_ms)
if btn.value():
flash_led(i, on_ms=160)
while btn.value():
time.sleep_ms(10)
return i
if timeout_ms is not None and time.ticks_diff(time.ticks_ms(), start) > timeout_ms:
return None
def play_sequence(seq, on_ms):
time.sleep_ms(250)
for idx in seq:
leds[idx].value(1)
beep(520 + idx*150, on_ms/1000)
leds[idx].value(0)
time.sleep_ms(max(80, on_ms//2))
def start_anim():
for f in (650, 820, 980):
beep(f, 0.10)
time.sleep_ms(120)
def game_over_anim():
for _ in range(2):
for led in leds: led.value(1)
beep(240, 0.20)
for led in leds: led.value(0)
time.sleep_ms(120)
beep(180, 0.30)
def main():
try:
random.seed(time.ticks_ms() & 0xFFFFFFFF)
except:
pass
score = 0
seq = []
show_digit(0)
start_anim()
while True:
# extend sequence
seq.append(random.randint(0, 3))
# playback speed increases with length
on_ms = max(140, 420 - len(seq)*18)
play_sequence(seq, on_ms)
# input phase with timeout
timeout_ms = 5000 + len(seq)*600
ok = True
for expected in seq:
btn = wait_button(timeout_ms=timeout_ms)
if btn is None or btn != expected:
ok = False
break
if ok:
score = min(score + 1, 9) # single digit 0..9
show_digit(score)
beep(1080, 0.12)
time.sleep_ms(280)
else:
game_over_anim()
seq = []
show_digit(0)
time.sleep_ms(600)
print("Your score is", score)
score = 0
if __name__ == "__main__":
main()