Skip to content

Instantly share code, notes, and snippets.

@Kraiden
Created November 25, 2024 07:17
Show Gist options
  • Save Kraiden/5393bc30f4c29d8b8dd51b4c21c0c829 to your computer and use it in GitHub Desktop.
Save Kraiden/5393bc30f4c29d8b8dd51b4c21c0c829 to your computer and use it in GitHub Desktop.
Snake on an RGB keyboard
import os
import random
import time
from pynput import keyboard
base_path = "/sys/class/leds/rgb:kbd_backlight"
brightness_path = os.path.join(base_path, "brightness")
# Globals
snake = [(3, 3), (3, 2), (3, 1)] # Initial snake position
direction = "RIGHT" # Initial direction
food = None
game_running = True
grid_state = {} # Tracks the current color of each cell
def main():
if not init():
return
print("Starting Snake...")
spawn_food()
# Start the keyboard listener for input
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
game_loop()
listener.join()
def init():
if not os.path.exists(brightness_path):
print(f"Brightness path '{brightness_path}' not found. Are you sure the device supports it?")
return False
else:
reset_grid()
return True
def spawn_food():
global food
while True:
food = (random.randint(0, 5), random.randint(0, 19))
if food not in snake: # Ensure food doesn't spawn on the snake
break
def game_loop():
global snake, food, direction, game_running
while game_running:
# Move the snake
head = snake[0]
if direction == "UP":
new_head = (head[0] - 1, head[1])
elif direction == "DOWN":
new_head = (head[0] + 1, head[1])
elif direction == "LEFT":
new_head = (head[0], head[1] - 1)
elif direction == "RIGHT":
new_head = (head[0], head[1] + 1)
# Check collisions
if (
new_head[0] < 0 or new_head[0] >= 6 or
new_head[1] < 0 or new_head[1] >= 20 or
new_head in snake
):
for segment in snake:
update_cell(segment, (255,255,255))
game_running = False
print("Game Over! Your score:", len(snake) - 3)
break
# Check food collision
if new_head == food:
snake.insert(0, new_head) # Grow the snake
spawn_food() # Place new food
else:
snake.insert(0, new_head)
tail = snake.pop() # Move the snake
if tail == (0,0):
update_cell(tail, (255, 255, 0)) # Escape button
else:
update_cell(tail, (0, 0, 0)) # Clear the old tail
# Update the grid
update_cell(food, (0, 255, 0)) # Food color
update_cell(new_head, (255, 0, 0)) # Snake head color
time.sleep(0.3) # Game speed
def reset_grid():
"""Reset the entire grid to black."""
global grid_state
grid_state = {}
for key in range(120):
grid_state[key] = (0, 0, 0) # Set all cells to black
set_colour((0, 0, 0), key)
update_cell((0,0), (255, 255, 0)) # Escape button
def update_cell(coords, color):
"""Update a single cell if its color has changed."""
global grid_state
key = coors_to_key(coords[1], coords[0])
if grid_state.get(key) != color: # Only update if color has changed
grid_state[key] = color
set_colour(color, key)
def set_colour(color, key):
write_value(key_to_path(key), f"{color[0]} {color[1]} {color[2]}")
def on_press(key):
global direction
try:
if key == keyboard.Key.up and direction != "DOWN":
direction = "UP"
elif key == keyboard.Key.down and direction != "UP":
direction = "DOWN"
elif key == keyboard.Key.left and direction != "RIGHT":
direction = "LEFT"
elif key == keyboard.Key.right and direction != "LEFT":
direction = "RIGHT"
except AttributeError:
pass # Ignore other keys
def on_release(key):
if key == keyboard.Key.esc:
set_base_colors()
global game_running
game_running = False
return False # Exit the game
def write_value(path, value):
try:
with open(path, 'w') as f:
f.write(str(value))
except Exception as e:
print(f"Failed to set value: {e}")
def key_to_path(key):
if key > 0:
return f"{base_path}_{key}/multi_intensity"
else:
return f"{base_path}/multi_intensity"
def coors_to_key(x, y):
return y * 20 + x
def lerp_rgb(color1, color2, steps = 120):
if steps < 2:
raise ValueError("Steps must be at least 2 to interpolate between colors.")
# Calculate the step size for each channel
step_colors = [
[
int(color1[i] + (color2[i] - color1[i]) * t / (steps - 1))
for i in range(3)
]
for t in range(steps)
]
return step_colors
def set_base_colors():
grad_start = (0,255,0)
grad_end = (0,0,255)
color_wheel = lerp_rgb(grad_start,grad_end)
for i, color in enumerate(color_wheel, 0):
set_colour(color, i)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment