Lights Out game for MacroPad (Adabox 019)

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mccollam
 
Posts: 6
Joined: Fri Mar 10, 2017 3:00 pm

Lights Out game for MacroPad (Adabox 019)

Post by mccollam »

The light-up buttons on the MacroPad made me think of an old game, Lights Out (https://www.wikiwand.com/en/Lights_Out_(game)). Buttons are lit up in a pattern, and you toggle lights by pressing buttons. The trick is that pushing a button toggles that light plus the lights on each side!

Image

The code is pretty simple and is up on GitHub here: https://github.com/mccollam/MacroPadLightsOut

I've only added a few levels, but they're all solvable. PRs welcome for new ones! :)

User avatar
dastels
 
Posts: 15608
Joined: Tue Oct 20, 2015 3:22 pm

Re: Lights Out game for MacroPad (Adabox 019)

Post by dastels »

Nicely done!

Dave

User avatar
wilsonRL
 
Posts: 11
Joined: Tue Jul 13, 2021 10:09 pm

Re: Lights Out game for MacroPad (Adabox 019)

Post by wilsonRL »

I also wrote a lights out game and enjoyed comparing our different approaches to writing the code. It's hard for me to believe that they both do the same thing because the code looks so different (to my untrained eye at least). I though I would share my code here in case it helps anyone:

Code: Select all

"""
Lights Out for Adabox019 MACROPAD
Rebecca Wilson
August 23, 2021
"""

# The objective of this game is to turn off all of the lights.
# When you press a button it toggles the light on itself and all adjacent buttons.
# Turn the encoder knob to change levels and press the encoder button to start a game.

from adafruit_macropad import MacroPad

macropad = MacroPad()
macropad.pixels.brightness = 0.1

# this is a list that contains a list of each button location and the location of its adjacent neighbors that need to be toggled if it's pressed
neighbors = [[0,1,3],[0,1,2,4],[1,2,5],[0,3,4,6],[1,3,4,5,7],[2,4,5,8],[3,6,7,9],[4,6,7,8,10],[5,7,8,11],[6,9,10],[7,9,10,11],[8,10,11]]

# this list will store an object with information for each button (the button_info class - see below)
buttons = []

# the following lists are used to set the button state (on = 1 or off = 0) for each level (L1 - L20)
# the CLEAR_BOARD list starts with all of the lights off - you can use this to create a solveable game:
# just press buttons until you like the pattern of lights that are on and record the pattern as a new level
CLEAR_BOARD = [0,0,0,0,0,0,0,0,0,0,0,0]

L1 = [0,0,0,0,1,0,1,1,1,0,1,0]
L2 = [1,0,1,0,0,0,0,0,0,1,0,1]
L3 = [1,1,1,1,0,1,1,0,1,1,1,1]
L4 = [1,0,1,1,0,0,0,0,1,1,1,1]
L5 = [1,1,1,0,1,0,0,1,0,1,1,1]
L6 = [0,1,0,1,0,1,1,0,1,0,1,0]
L7 = [1,0,1,0,1,0,0,1,0,1,0,1]
L8 = [1,0,1,1,1,1,1,1,1,1,0,1]
L9 = [0,0,0,1,0,1,1,0,1,0,0,0]
L10 = [0,0,1,0,1,1,1,1,0,0,1,1]
L11 = [1,0,1,0,0,0,1,0,1,1,0,1]
L12 = [0,1,0,1,0,1,0,1,0,0,1,0]
L13 = [0,0,1,1,0,0,0,0,1,1,0,0]
L14 = [0,0,0,0,1,0,0,0,0,1,0,1]
L15 = [0,0,0,0,0,0,1,0,1,0,0,0]
L16 = [0,1,0,0,1,0,0,1,0,0,1,0]
L17 = [1,1,1,0,0,0,0,0,0,1,1,1]
L18 = [0,1,0,1,0,1,1,1,1,1,1,1]
L19 = [1,1,1,0,1,0,0,1,0,0,1,0]
L20 = [1,0,1,1,0,1,1,1,1,0,0,0]

# this is a list of the above level lists
# if you add a new level, don't forget to add it to this list
LEVELS = [L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L15,L16,L17,L18,L19,L20]

# key colors - just in case you want to choose a different color for the button lights
RED = (255,0,0)
ORANGE = (255,25,0)
YELLOW = (255, 200, 0)
SPRING = (0,255,50)
GREEN = (0,255,0)
CYAN = (0,255,125)
SKY = (0,255,255)
CLOUD = (0,125,255)
BLUE = (0,0,255)
INDIGO = (50,0,255)
MAGENTA = (125,0,125)
PINK = (255,0,50)

# this class keeps track of the key position, color and state
# it also allows us to toggle the light on and off based on the button's state
class button_info:
    def __init__(self,location,state):
        self.key_location = location
        self.neo_color = MAGENTA
        self.state = state  # 1 = on / 0 = off

    def show(self):
        macropad.pixels[self.key_location] = self.neo_color
        self.state = 1

    def hide(self):
        macropad.pixels[self.key_location] = (0,0,0)
        self.state = 0

    def toggle(self):
        if self.state is 1: # if light is on then turn light off
            self.hide()
        else:               # if light is off then turn light on
            self.show()

# when called populates the button list with an object of each button_info class for each key on the macropad (see above)
def create_board():
    for i in range(12):
        buttons.append(button_info(i,CLEAR_BOARD[i]))

# sets the state of each button_info object to zero and then turns off all the lights
def reset_board():
    for i in range(12):
        buttons[i].hide()

# shows game title text on the macropad's display
text_lines = macropad.display_text(title='Lights Out')
text_lines.show()

# populate the button list with an object of each button_info class for each key on the macropad (see above)
create_board()

# variable to keep track of of whether all the lights are off
score = 0

# main loop
while True:

    # the position of the encoder knob sets the game level (from the LEVELS list)
    # % 20 loops through the LEVELS list
    # note - if you change the number of levels, change this value to match the new number of levels
    # note - the encoder knob starts at position zero regardless of its physical starting position
    encoder_position = macropad.encoder % 20
    # prints encoder position (game level) to macropad's display
    text_lines[1].text = 'Level: {0} '.format(encoder_position + 1)

    # watches for encoder knob to be pressed
    macropad.encoder_switch_debounced.update()

    # watches for keys to be pressed
    key_event = macropad.keys.events.get()

    # when the encoder switch is pressed, this resets the board and creates the game level based on the encoder position
    if macropad.encoder_switch_debounced.pressed:
        reset_board()
        text_lines[2].text = ''
        for i in range(12):
            if LEVELS[encoder_position][i] == 1:
                buttons[i].show() 

    
    # when a key is pressed 
    if key_event:
        # toggle that key and it's neighbors
        if key_event.pressed:
            for item in neighbors[key_event.key_number]:
                buttons[item].toggle()
                print(key_event.key_number)
            # check all of the button states and count the ones that are turned off
            for button in buttons:
                if button.state == 0:
                    score += 1
                # if all lights are turned off print 'you win' to the macropad display
                if score == 12:
                    text_lines[2].text = 'YOU WIN!'
    
    # reset the score 
    score = 0

Locked
Please be positive and constructive with your questions and comments.

Return to “AdaBox! Show us what you made!”