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)