code.py
  1  # SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  """
  6  NeoTrellis M4 Express Memory Game
  7  
  8  Adafruit invests time and resources providing this open source code.
  9  Please support Adafruit and open source hardware by purchasing
 10  products from Adafruit!
 11  
 12  Written by Dave Astels for Adafruit Industries
 13  Copyright (c) 2018 Adafruit Industries
 14  Licensed under the MIT license.
 15  
 16  All text above must be included in any redistribution.
 17  """
 18  
 19  # pylint: disable=stop-iteration-return
 20  
 21  import time
 22  import random
 23  from rainbowio import colorwheel
 24  import adafruit_trellism4
 25  
 26  COLORS = [0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF]
 27  
 28  trellis = adafruit_trellism4.TrellisM4Express(rotation=0)
 29  trellis.pixels.brightness = 0.1
 30  trellis.pixels.fill(0)
 31  
 32  pixel_colors = [None] * 32
 33  found_pairs = 0
 34  previously_pressed = set([])
 35  first_pixel = None
 36  
 37  key_pressed = None
 38  
 39  def index_of(coord):
 40      x, y = coord
 41      return y * 8 + x
 42  
 43  
 44  def cycle_sequence(seq):
 45      while True:
 46          for elem in seq:
 47              yield elem
 48  
 49  def rainbow_lamp(seq):
 50      g = cycle_sequence(seq)
 51      while True:
 52          trellis.pixels.fill(colorwheel(next(g)))
 53          yield
 54  
 55  def splash():
 56      rainbow = rainbow_lamp(range(0, 256, 8))
 57      for _ in range(64):
 58          next(rainbow)
 59          time.sleep(0.005)
 60  
 61  def assign_colors():
 62      unassigned = [(x, y) for x in range(8) for y in range(4)]
 63      while unassigned:
 64          first_of_pair = random.choice(unassigned)
 65          unassigned.remove(first_of_pair)
 66          second_of_pair = random.choice(unassigned)
 67          unassigned.remove(second_of_pair)
 68          random_color = random.choice(COLORS)
 69          pixel_colors[index_of(first_of_pair)] = random_color
 70          pixel_colors[index_of(second_of_pair)] = random_color
 71  
 72  def handle_key(key, _found_pairs, _first_pixel):
 73      if key is None:
 74          return _found_pairs, _first_pixel
 75      key_color = pixel_colors[index_of(key)]
 76      if key_color is not None:
 77          trellis.pixels[key] = pixel_colors[index_of(key)]
 78          time.sleep(0.5)
 79          if _first_pixel and _first_pixel != key:
 80              if key_color == pixel_colors[index_of(_first_pixel)]:
 81                  pixel_colors[index_of(_first_pixel)] = None
 82                  pixel_colors[index_of(key)] = None
 83                  for _ in range(5):
 84                      trellis.pixels[_first_pixel] = 0xFFFFFF
 85                      trellis.pixels[key] = 0xFFFFFF
 86                      time.sleep(0.1)
 87                      trellis.pixels[_first_pixel] = 0x000000
 88                      trellis.pixels[key] = 0x000000
 89                      time.sleep(0.1)
 90                  trellis.pixels[_first_pixel] = 0x444444
 91                  trellis.pixels[key] = 0x444444
 92                  return _found_pairs + 1, None
 93              else:
 94                  trellis.pixels[_first_pixel] = 0x000000
 95                  trellis.pixels[key] = 0x000000
 96                  return _found_pairs, None
 97          else:
 98              return _found_pairs, key
 99      return _found_pairs, None
100  
101  def check_for_key(last_pressed):
102      now_pressed = set(trellis.pressed_keys)
103      new_presses = now_pressed - last_pressed
104      if new_presses:
105          return now_pressed, list(new_presses)[0]
106      return now_pressed, None
107  
108  demo_mode_enabled = True
109  while True:
110      trellis.pixels.fill(0x000000)
111      assign_colors()
112      found_pairs = 0
113      first_pixel = None
114      remaining = [(x, y) for x in range(8) for y in range(4)]
115      while found_pairs < 16:
116          if demo_mode_enabled:
117              previously_pressed, key_pressed = check_for_key(previously_pressed)
118              if key_pressed:
119                  demo_mode_enabled = False
120                  break
121              first = random.choice(remaining)
122              remaining.remove(first)
123              found_pairs, first_pixel = handle_key(first, found_pairs, first_pixel)
124              previously_pressed, key_pressed = check_for_key(previously_pressed)
125              if key_pressed:
126                  demo_mode_enabled = False
127                  break
128              c = pixel_colors[index_of(first)]
129              match = random.choice([x for x in remaining if pixel_colors[index_of(x)] == c])
130              found_pairs, first_pixel = handle_key(match, found_pairs, first_pixel)
131              remaining.remove(match)
132          else:
133              previously_pressed, key_pressed = check_for_key(previously_pressed)
134              found_pairs, first_pixel = handle_key(key_pressed, found_pairs, first_pixel)
135      if found_pairs == 16:
136          splash()