Skip to content

Commit e8d8a06

Browse files
committed
Implement snake game
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 60483ec commit e8d8a06

File tree

1 file changed

+181
-2
lines changed

1 file changed

+181
-2
lines changed

control.py

Lines changed: 181 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from datetime import datetime, timedelta
77
import random
88
import math
9+
import sys
910

1011
# Need to install
1112
import serial
@@ -58,9 +59,10 @@ def main():
5859
parser.add_argument("--breathing", help="Breathing of the current pattern",
5960
action="store_true")
6061
parser.add_argument("--eq", help="Equalizer", nargs='+', type=int)
61-
parser.add_argument("--wpm", help="WPM Demo", action="store_true")
6262
parser.add_argument(
6363
"--random-eq", help="Random Equalizer", action="store_true")
64+
parser.add_argument("--wpm", help="WPM Demo", action="store_true")
65+
parser.add_argument("--snake", help="Snake", action="store_true")
6466
parser.add_argument(
6567
"--all-brightnesses", help="Show every pixel in a different brightness", action="store_true")
6668
parser.add_argument("--serial-dev", help="Change the serial dev. Probably /dev/ttyACM0 on Linux, COM0 on Windows",
@@ -107,6 +109,8 @@ def main():
107109
breathing()
108110
elif args.wpm:
109111
wpm_demo()
112+
elif args.snake:
113+
snake()
110114
elif args.eq is not None:
111115
eq(args.eq)
112116
elif args.random_eq:
@@ -302,6 +306,125 @@ def breathing():
302306
brightness(50 + i*20)
303307

304308

309+
direction = None
310+
body = []
311+
312+
313+
def opposite_direction(direction):
314+
from getkey import keys
315+
if direction == keys.RIGHT:
316+
return keys.LEFT
317+
elif direction == keys.LEFT:
318+
return keys.RIGHT
319+
elif direction == keys.UP:
320+
return keys.DOWN
321+
elif direction == keys.DOWN:
322+
return keys.UP
323+
return direction
324+
325+
326+
def keyscan():
327+
from getkey import getkey, keys
328+
global direction
329+
global body
330+
331+
while True:
332+
current_dir = direction
333+
key = getkey()
334+
if key in [keys.RIGHT, keys.UP, keys.LEFT, keys.DOWN]:
335+
# Don't allow accidental suicide if we have a body
336+
if key == opposite_direction(current_dir) and body:
337+
continue
338+
direction = key
339+
340+
341+
def game_over():
342+
global body
343+
while True:
344+
show_string('GAME ')
345+
time.sleep(0.75)
346+
show_string('OVER!')
347+
time.sleep(0.75)
348+
score = len(body)
349+
show_string(f'{score:>3} P')
350+
time.sleep(0.75)
351+
352+
353+
def snake():
354+
from getkey import keys
355+
global direction
356+
global body
357+
head = (0, 0)
358+
direction = keys.DOWN
359+
food = (0, 0)
360+
while food == head:
361+
food = (random.randint(0, WIDTH-1),
362+
random.randint(0, HEIGHT-1))
363+
364+
# Setting
365+
WRAP = False
366+
367+
thread = threading.Thread(target=keyscan, args=(), daemon=True)
368+
thread.start()
369+
370+
prev = datetime.now()
371+
while True:
372+
now = datetime.now()
373+
delta = (now - prev) / timedelta(milliseconds=1)
374+
375+
if delta > 200:
376+
prev = now
377+
else:
378+
continue
379+
380+
# Update position
381+
(x, y) = head
382+
oldhead = head
383+
if direction == keys.RIGHT:
384+
head = (x+1, y)
385+
elif direction == keys.LEFT:
386+
head = (x-1, y)
387+
elif direction == keys.UP:
388+
head = (x, y-1)
389+
elif direction == keys.DOWN:
390+
head = (x, y+1)
391+
392+
# Detect edge condition
393+
(x, y) = head
394+
if head in body:
395+
return game_over()
396+
elif x >= WIDTH or x < 0 or y >= HEIGHT or y < 0:
397+
if WRAP:
398+
if x >= WIDTH:
399+
x = 0
400+
elif x < 0:
401+
x = WIDTH-1
402+
elif y >= HEIGHT:
403+
y = 0
404+
elif y < 0:
405+
y = HEIGHT-1
406+
head = (x, y)
407+
else:
408+
return game_over()
409+
elif head == food:
410+
body.insert(0, oldhead)
411+
while food == head:
412+
food = (random.randint(0, WIDTH-1),
413+
random.randint(0, HEIGHT-1))
414+
elif body:
415+
body.pop()
416+
body.insert(0, oldhead)
417+
418+
# Draw on screen
419+
matrix = [[0 for _ in range(HEIGHT)] for _ in range(WIDTH)]
420+
matrix[x][y] = 1
421+
matrix[food[0]][food[1]] = 1
422+
for bodypart in body:
423+
(x, y) = bodypart
424+
matrix[x][y] = 1
425+
render_matrix(matrix)
426+
427+
305428
def wpm_demo():
306429
"""Capture keypresses and calculate the WPM of the last 10 seconds
307430
TODO: I'm not sure my calculation is right."""
@@ -456,7 +579,7 @@ def clock():
456579
def send_command(command):
457580
"""Send a command to the device.
458581
Opens new serial connection every time"""
459-
print(f"Sending command: {command}")
582+
# print(f"Sending command: {command}")
460583
global SERIAL_DEV
461584
with serial.Serial(SERIAL_DEV, 115200) as s:
462585
s.write(command)
@@ -903,6 +1026,62 @@ def convert_font(num):
9031026
1, 0, 0, 0, 1,
9041027
1, 1, 1, 1, 0,
9051028
],
1029+
'O': [
1030+
0, 1, 1, 1, 0,
1031+
1, 0, 0, 0, 1,
1032+
1, 0, 0, 0, 1,
1033+
1, 0, 0, 0, 1,
1034+
1, 0, 0, 0, 1,
1035+
0, 1, 1, 1, 0,
1036+
],
1037+
'V': [
1038+
1, 0, 0, 0, 1,
1039+
1, 0, 0, 0, 1,
1040+
0, 1, 0, 1, 1,
1041+
0, 1, 0, 1, 1,
1042+
0, 0, 1, 0, 0,
1043+
0, 0, 1, 0, 0,
1044+
],
1045+
'E': [
1046+
1, 1, 1, 1, 1,
1047+
1, 0, 0, 0, 0,
1048+
1, 1, 1, 1, 1,
1049+
1, 0, 0, 0, 0,
1050+
1, 0, 0, 0, 0,
1051+
1, 1, 1, 1, 1,
1052+
],
1053+
'R': [
1054+
1, 1, 1, 1, 0,
1055+
1, 0, 0, 1, 0,
1056+
1, 1, 1, 1, 0,
1057+
1, 1, 0, 0, 0,
1058+
1, 0, 1, 0, 0,
1059+
1, 0, 0, 1, 0,
1060+
],
1061+
'G': [
1062+
0, 1, 1, 1, 0,
1063+
1, 0, 0, 0, 0,
1064+
1, 0, 1, 1, 1,
1065+
1, 0, 0, 0, 1,
1066+
1, 0, 0, 0, 1,
1067+
0, 1, 1, 1, 0,
1068+
],
1069+
'M': [
1070+
0, 0, 0, 0, 0,
1071+
0, 1, 0, 1, 0,
1072+
1, 0, 1, 0, 1,
1073+
1, 0, 1, 0, 1,
1074+
1, 0, 1, 0, 1,
1075+
1, 0, 1, 0, 1,
1076+
],
1077+
'P': [
1078+
1, 1, 1, 0, 0,
1079+
1, 0, 0, 1, 0,
1080+
1, 0, 0, 1, 0,
1081+
1, 1, 1, 0, 0,
1082+
1, 0, 0, 0, 0,
1083+
1, 0, 0, 0, 0,
1084+
],
9061085
}
9071086
if num in font:
9081087
return font[num]

0 commit comments

Comments
 (0)