/ PyRuler_Simon_Game / code.py
code.py
1 # SPDX-FileCopyrightText: 2019 Isaac Wellish for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 """ 6 This example runs the 'Simon' game on the PyRuler. 7 Memorize each led sequence and tap the corresponding 8 touch pads on the pyruler to advance to each new sequence. 9 Code adapted from Miguel Grinberg's Simon game for Circuit Playground Express 10 11 """ 12 13 import time 14 import random 15 import board 16 from rainbowio import colorwheel 17 from digitalio import DigitalInOut, Direction 18 import touchio 19 import adafruit_dotstar 20 21 # Initialize dot star led 22 pixels = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 23 1, brightness=0.1) 24 red = (255,0,0) 25 green = (0,255,0) 26 blue = (0,0,255) 27 28 led = DigitalInOut(board.D13) 29 led.direction = Direction.OUTPUT 30 31 touches = [DigitalInOut(board.CAP0)] 32 for p in (board.CAP1, board.CAP2, board.CAP3): 33 touches.append(touchio.TouchIn(p)) 34 35 leds = [] 36 for p in (board.LED4, board.LED5, board.LED6, board.LED7): 37 led = DigitalInOut(p) 38 led.direction = Direction.OUTPUT 39 leds.append(led) 40 41 cap_touches = [False, False, False, False] 42 43 44 def rainbow_cycle(wait): 45 for j in range(255): 46 for i in range(len(pixels)): 47 rc_index = (i * 256 // len(pixels)) + j 48 pixels[i] = colorwheel(rc_index & 255) 49 time.sleep(wait) 50 51 def read_caps(): 52 t0_count = 0 53 t0 = touches[0] 54 t0.direction = Direction.OUTPUT 55 t0.value = True 56 t0.direction = Direction.INPUT 57 # funky idea but we can 'diy' the one non-hardware captouch device by hand 58 # by reading the drooping voltage on a tri-state pin. 59 t0_count = t0.value + t0.value + t0.value + t0.value + t0.value + \ 60 t0.value + t0.value + t0.value + t0.value + t0.value + \ 61 t0.value + t0.value + t0.value + t0.value + t0.value 62 cap_touches[0] = t0_count > 2 63 cap_touches[1] = touches[1].raw_value > 3000 64 cap_touches[2] = touches[2].raw_value > 3000 65 cap_touches[3] = touches[3].raw_value > 3000 66 return cap_touches 67 68 def timeout_touch(timeout=3): 69 start_time = time.monotonic() # start 3 second timer waiting for user input 70 while time.monotonic() - start_time < timeout: 71 caps = read_caps() 72 for i,c in enumerate(caps): 73 if c: 74 return i 75 76 def light_cap(cap, duration=0.5): 77 # turn the LED for the selected cap on 78 leds[cap].value = True 79 time.sleep(duration) 80 leds[cap].value = False 81 time.sleep(duration) 82 83 def play_sequence(seq): 84 duration = max(0.1, 1 - len(sequence) * 0.05) 85 for cap in seq: 86 light_cap(cap, duration) 87 88 def read_sequence(seq): 89 pixels.fill(green) 90 for cap in seq: 91 if timeout_touch() != cap: 92 # the player made a mistake! 93 return False 94 light_cap(cap, 0.5) 95 return True 96 97 while True: 98 # led light sequence at beginning of each game 99 pixels.fill(blue) 100 time.sleep(1) 101 for led in leds: 102 led.value = True 103 time.sleep(0.25) 104 for led in leds: 105 led.value = False 106 sequence = [] 107 while True: 108 pixels.fill(blue) # blue for showing user sequence 109 time.sleep(1) 110 sequence.append(random.randint(0, 3)) # add new light to sequence each time 111 play_sequence(sequence) # show the sequence 112 if not read_sequence(sequence): # if user inputs wrong sequence, gameover 113 # game over, make dot star red 114 pixels.fill(red) 115 time.sleep(3) 116 print("gameover") 117 break 118 else: 119 print("Next sequence unlocked!") 120 rainbow_cycle(0) # Dot star animation after each correct sequence 121 pixels.fill(0) 122 time.sleep(1)