Skip to content

Instantly share code, notes, and snippets.

@jacob-herr
Last active April 5, 2023 21:06
Show Gist options
  • Save jacob-herr/ba9c54845a2e4f03bf43c108a7645b54 to your computer and use it in GitHub Desktop.
Save jacob-herr/ba9c54845a2e4f03bf43c108a7645b54 to your computer and use it in GitHub Desktop.
import random
from time import sleep
import math
import pynput
from threading import *
from pynput.keyboard import Listener
from termcolor import colored
from os import system
# all of the variables here are needed to break out of while loops using pynput
downkey = False
leftkey = False
rightkey = False
upkey = False
dead = False
framerate = 0.075
score = 0
boardlen = 25
boardwidth = 50
class Board:
def __init__(self, rows, columns,framerate):
self.framerate = framerate
self.board = [[' ' for column in range(columns)] for row in range(rows)]
self.rows = rows
self.columns = columns
def draw_board(self,score):
system('clear')
print(f'score : {score}')
print(' ----'+'-' * (len(range(self.columns)) - 1),)
for i in range(self.rows):
print(' | '+''.join(self.board[i])+ '|',)
print(' ', end= '')
print( ' \u203E\u203E'+ '\u203E' * (len(range(self.columns))))
sleep(self.framerate)
def placefood(self):
self.food = colored('*', 'red')
while True:
y = random.randint(0,self.rows-1)
x = random.randint(0, self.columns-1)
if self.board[y][x] == ' ':
self.board[y][x] = self.food
return
# info to clean up the snake class
class Head:
def __init__(self,starty,startx):
self.head = colored('0', 'magenta')
self.y = starty
self.x = startx
class Snake():
def __init__(self, board, head):
self.length = 1
# y and x directions need to be etsablished in init so i can manipulate
# them later with other functions.
self.ydir = 0
self.xdir = 0
self.head = head
self.board = board
self.moves = []
self.snakebody = colored('#', 'green')
def check_and_replace_food(self):
if self.board.board[self.head.y][self.head.x] == self.board.food:
self.length += 1
self.board.placefood()
def checkdeath(self):
global dead # global needed for pynput to stop taking input.
dead = False
try:
if self.board.board[self.head.y][self.head.x] == self.snakebody:
dead = True
if self.head.y < 0 or self.head.x < 0:
dead = True
except:
dead = True
if dead:
print('\n' * 5 + 'YOU DIED :(' + '\n' * 4)
listener.stop()
exit()
def trim_and_place_body(self):
if len(self.moves) >= 1:
self.board.board[self.moves[-self.length][0]][self.moves[-self.length][1]] = ' '
for i in range(1,self.length):
self.board.board[self.moves[-i][0]][self.moves[-i][1]] = self.snakebody
def movehead(self, ydir, xdir):
self.ydir = ydir
self.xdir = xdir
self.head.y = self.head.y + ydir
self.head.x = self.head.x + xdir
def movement(self, ydir, xdir):
self.trim_and_place_body()
self.movehead(ydir, xdir)
self.checkdeath()
self.moves.append([self.head.y,self.head.x])
self.check_and_replace_food()
self.board.board[self.head.y][self.head.x] = self.head.head
self.board.draw_board(self.length - 1)
gameboard = Board(boardlen ,boardwidth, framerate)
gamehead = Head(math.floor(gameboard.rows/2),math.floor(gameboard.columns/2))
gamesnake = Snake(gameboard, gamehead)
gameboard.placefood()
gameboard.draw_board(score)
def down():
while downkey:
gamesnake.movement(1,0)
def up():
while upkey:
gamesnake.movement(-1,0)
def left():
while leftkey:
gamesnake.movement(0,-1)
def right():
while rightkey:
gamesnake.movement(0,1)
def keystrokes(Key):
global downkey
global upkey # all of these had to be global for pynput
global leftkey
global rightkey
if Key == Key.down and not gamesnake.ydir == -1:
if not downkey :
upkey = False
leftkey = False #blocks all other threads and activates a thread for the given key
rightkey = False
downkey = True
Thread(target=down).start()
# this repeats for all 3 other keystrokes no way around the repition,
# pynput is being weird.
elif Key == Key.up and not gamesnake.ydir == 1:
if not upkey:
downkey = False
leftkey = False
rightkey = False
upkey = True
Thread(target=up).start()
elif Key == Key.left and not gamesnake.xdir == 1:
if not leftkey:
downkey = False
upkey = False
rightkey = False
leftkey = True
Thread(target=left).start()
elif Key == Key.right and not gamesnake.xdir == -1:
if not rightkey:
downkey = False
upkey = False
leftkey = False
rightkey = True
Thread(target=right).start()
# how pynput reads keystrokes.
with Listener(on_press=keystrokes) as listener:
listener.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment