Raspberry Pi Pico
This project is based on a handheld electronic game that was developed in the 1970s. The game consists of 4 coloured buttons. The buttons light up when they are pressed and a different tone is played for each button. In each round of the game, the microcontroller lights up a sequence of buttons. The player has to press the buttons in the same sequence. After each round, the length of the sequence is increased by 1.
I have some nice LED buttons to use for this. This makes for a tidier circuit but you can do the same thing without using these.
The Fritzing diagram shows the same concept using separate buttons and LEDs.
I found it hard to manage the flow of the game using interrupts. I therefore switched back to using a while loop and monitoring changes in the game state.
from machine import PWM, Pin from time import sleep from random import randint # buzzer, frequency, duration - play tone subroutine def tone(frequency,duration): buzzer.duty_u16(volume) buzzer.freq(frequency) sleep(duration) buzzer.duty_u16(0) # frequency - plays until stopped def note_on(frequency): buzzer.duty_u16(volume) buzzer.freq(frequency) # stop the noise def note_off(): buzzer.duty_u16(0) def GetRandomSequence(): return [randint(0,3) for i in range(100)] def PlaySequence(t,s): for i in range(t): leds[s[i]].value(1) tone(notes[s[i]],0.5) leds[s[i]].value(0) sleep(0.2) def Win(): for i in range(4): for j in range(4): leds[j].value(1) tone(notes[j], 0.05) leds[j].value(0) def Loss(): tone(131,0.5) sleep(1.5) def PlayGame(): turn = 0 sequence = GetRandomSequence() userSequence = *100 seqlen = 0 playing = True played = False while playing==True: if turn==0: # Just started Win() turn = turn + 1 if seqlen==0 and played==False: # Sequence needs playing PlaySequence(turn, sequence) played = True elif seqlen==turn: # User has entered the sequence Win() played = False turn = turn + 1 seqlen = 0 else: # User still entering pattern for i in range(0,4): if btns[i].value()==0: userSequence[seqlen] = i if userSequence[seqlen]!=sequence[seqlen]: Loss() playing = False else: seqlen = seqlen + 1 leds[i].value(1) tone(notes[i], 0.5) leds[i].value(0) # define the pin to use for buzzing buzzer = PWM(Pin(16)) # the duty cycle to use when the note is on volume = 2512 # button pins btn_pins = [21,20,19,18] # led pins led_pins = [28,27,26,22] # notes for our Simon game notes = [659, 880, 330, 554] # configure button and led pins in new lists btns =  leds =  for i in range(4): btns.append(Pin(btn_pins[i], Pin.IN, Pin.PULL_UP)) leds.append(Pin(led_pins[i], Pin.OUT))
To start the game, type PlayGame() in the shell and press enter. It uses a random sequence of no more than 100 lights. This is just the basic outline of the game. It needs some development to improve it. This might be some more equipment to improve the user experience (a scoreboard, for example) or some improvement to the game play, like speeding up the playback the longer the sequence being played.