# Model: GPT-5 Thinking (2025-08-30)
# Prompt(s):
# 1) "In any code you create, put the name and version of the model at the top, and the prompt used to generate the code at the top as a comment in the code. Import any Python file I attach instead of putting its content in the code. If multiple prompts are needed, please put subsequent prompts after the original prompt"
# 2) "Generate a class called SpinGame in MicroPython that uses the classes Button, LCDDisplay, PassiveBuzzer, PrizeBox, and Wheel in the files attached here. The passive buzzer is connected to pin 16, and the button is connected to pin 15. Add buttonPressed and buttonReleased methods in the SpinGame class. When the button is pressed, use the wheel class to show the animation and use the returned slot to report to the player what prizes they won. Use a run method to run the game"
#
import utime
from Button import Button
from Displays import LCDDisplay
from Buzzer import PassiveBuzzer, tones
from PrizeBox import PrizeBox
from Wheel import Wheel
from Log import Log
# --- Hardware Configuration ---
# Match the wheel size to the number of LEDs on your NeoPixel ring
WHEEL_SIZE = 8
BUTTON_PIN = 15
BUZZER_PIN = 3
# Standard I2C pins for Raspberry Pi Pico (I2C bus 0)
LCD_SDA_PIN = 0
LCD_SCL_PIN = 1
class SpinGame:
"""
Controls the prize wheel game and coordinates all hardware modules.
"""
def __init__(self):
"""
Sets up the game components and initializes the system state.
"""
Log.i("Booting up SpinGame...")
# --- Hardware Setup ---
self.display = LCDDisplay(sda=LCD_SDA_PIN, scl=LCD_SCL_PIN)
self.buzzer = PassiveBuzzer(BUZZER_PIN, name="GameBuzzer")
self.wheel = Wheel(size=WHEEL_SIZE)
self.prize_box = PrizeBox(size=WHEEL_SIZE)
# Assign this class as the handler for button events.
# When pressed, it triggers self.buttonPressed()
self.button = Button(BUTTON_PIN, "SpinButton", handler=self)
# --- Internal State ---
self._spinning = False
self._running = False
Log.i("SpinGame setup complete.")
def _play_startup_sound(self):
"""Plays a quick melody to signal that the game is ready."""
self.buzzer.beep(tones['C4'], 100)
self.buzzer.beep(tones['E4'], 100)
self.buzzer.beep(tones['G4'], 100)
def _display_welcome_message(self):
"""Displays the welcome screen on the LCD."""
self.display.clear()
self.display.showText("Spin The Wheel!", row=0, col=1)
self.display.showText("Press to Play...", row=1, col=0)
def buttonPressed(self, name):
"""
Responds to button press events. This method drives the main game loop.
It's automatically triggered by the Button class's interrupt.
"""
# Prevent multiple spins from overlapping
if self._spinning:
Log.i("Button press ignored—wheel already spinning.")
return
self._spinning = True
Log.i("Initiating spin sequence...")
# --- Phase 1: Spin the Wheel ---
self.display.clear()
self.display.showText("Spinning...", row=0, col=2)
# Play sound during spin animation
self.buzzer.play(tones['C3'])
# Blocking call: runs LED animation and returns final slot
winning_slot = self.wheel.spin()
self.buzzer.stop() # End spin sound
# --- Phase 2: Reveal the Prize ---
prize = self.prize_box.getPrize(winning_slot)
Log.i(f"Prize awarded: {prize}")
self.display.clear()
if prize.type == "dollar":
self.display.showText("YOU WON!", row=0, col=4)
self.display.showText(f"${prize.value}", row=1, col=6)
# Play celebratory tones
self.buzzer.beep(tones['C5'], 150)
self.buzzer.beep(tones['G5'], 300)
elif prize.type == "retry":
self.display.showText("SO CLOSE!", row=0, col=3)
self.display.showText("Spin Again!", row=1, col=2)
self.buzzer.beep(tones['E4'], 150)
self.buzzer.beep(tones['E4'], 150)
else: # No prize won
self.display.showText("Sorry!", row=0, col=4)
self.display.showText("No Prize", row=1, col=3)
# Play consolation sound
self.buzzer.beep(tones['C3'], 400)
# --- Phase 3: Reset for Next Round ---
utime.sleep(3) # Pause to let player see result
self.prize_box.PickPrizes() # Refresh prize slots
self._display_welcome_message() # Show welcome again
self._spinning = False # Ready for next input
Log.i("System reset—awaiting next spin.")
def buttonReleased(self, name):
"""
Required by the Button class, but no action is needed when released.
"""
pass
def run(self):
"""
Launches the game, shows welcome message, and enters the main loop.
"""
self._running = True
self.display.clear()
self._play_startup_sound()
self._display_welcome_message()
self.prize_box.PickPrizes() # Initialize prize list
Log.i("Game active. Awaiting user input...")
try:
# Main loop remains idle; button press is handled via interrupt
while self._running:
utime.sleep(1)
except KeyboardInterrupt:
self._cleanup()
def _cleanup(self):
"""Safely powers down all connected components."""
Log.i("Shutting down system.")
self._running = False
self.display.clear()
self.display.showText("Goodbye!", row=0, col=4)
self.wheel.strip.off()
self.buzzer.stop()
self.button.setHandler(None) # Remove button event handler
if __name__ == "__main__":
game = SpinGame()
game.run()