Last active
April 5, 2023 21:06
-
-
Save jacob-herr/ba9c54845a2e4f03bf43c108a7645b54 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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