import os import random import time import numpy as np from pynput import keyboard class Snake: def __init__(self, x_bounds, y_bounds): self.x = int((x_bounds[1] - x_bounds[0] + 1)/4) self.y = int((y_bounds[1] - y_bounds[0] + 1)/4) self.vel = 1 self.x_bounds = x_bounds self.y_bounds = y_bounds self.tail = [(self.x, self.y)] self.growing = False def update(self): if self.vel == 1: self.x += 1 elif self.vel == 2: self.y += 1 elif self.vel == 3: self.x -= 1 elif self.vel == 0: self.y -= 1 if self.x > self.x_bounds[1] or self.x < self.x_bounds[0]: return 1 if self.y > self.y_bounds[1] or self.y < self.y_bounds[0]: return 1 self.tail.insert(0, (self.x, self.y)) if not self.growing: self.tail.pop() else: self.growing = False if (self.x, self.y) in self.tail[1:]: return 1 return 0 def contains(self, x, y): return (x, y) in self.tail def grow(self): self.growing = True class Food: def __init__(self, x_bounds, y_bounds, snake): rand_x = snake.x rand_y = snake.y while (rand_x, rand_y) in snake.tail: rand_x = random.randint(x_bounds[0], x_bounds[1]) rand_y = random.randint(y_bounds[0], y_bounds[1]) self.x = rand_x self.y = rand_y def on_release(key): global paused arrows = [keyboard.Key.up, keyboard.Key.right, keyboard.Key.down, keyboard.Key.left] if key == keyboard.Key.esc: # Stop listener return False elif key in arrows: new_dir = arrows.index(key) if (new_dir + 2) % 4 != last_dir: snake.vel = new_dir elif hasattr(key, 'char') and key.char == 'p': paused = not paused x_bounds = (0, 29) y_bounds = (0, 14) # Collect events until released with keyboard.Listener( on_press=None, on_release=on_release) as listener: snake = Snake(x_bounds, y_bounds) food = Food(x_bounds, y_bounds, snake) paused = False last_dir = 1 score = 0 with open("high_score.dat") as f: h_score = int(f.read().strip()) play = True while play: os.system('cls' if os.name == 'nt' else 'clear') if not paused: play = (snake.update() == 0) last_dir = snake.vel score_str = f"Score: {score}" hs_str = f"High Score: {h_score}" print(score_str + " ".join(['']*(32 - len(score_str) - len(hs_str) + 1)) + hs_str) print("_".join([''] * (x_bounds[1] - x_bounds[0] + 4))) for i in range((y_bounds[1] - y_bounds[0]) + 1): print("|", end="") for j in range((x_bounds[1] - x_bounds[0]) + 1): pause_start = int(((x_bounds[1] - x_bounds[0]) + 2 - len("Paused"))/2) pause_range = range(pause_start, pause_start + len("Paused")) over_start = int(((x_bounds[1] - x_bounds[0]) + 2 - len("Game Over")) / 2) over_range = range(over_start, over_start + len("Game Over")) n_h_s_start = int(((x_bounds[1] - x_bounds[0]) + 2 - len("New High Score!")) / 2) n_h_s_range = range(n_h_s_start, n_h_s_start + len("New High Score!")) if paused and i == int((y_bounds[1] - y_bounds[0])/2) and j in pause_range: print("Paused"[pause_range.index(j)], end="") elif not play and i == int((y_bounds[1] - y_bounds[0])/2) and j in over_range: print("Game Over"[over_range.index(j)], end="") elif not play and score == h_score and i == int((y_bounds[1] - y_bounds[0])/2) + 2 and j in n_h_s_range: print("New High Score!"[n_h_s_range.index(j)], end="") elif snake.contains(j, i): print(u"\u2588", end="") if food.x == j and food.y == i: snake.grow() food = Food(x_bounds, y_bounds, snake) score += 1 if score > h_score: h_score = score elif food.x == j and food.y == i: print("o", end="") else: print(" ", end="") print("|") print(u"\u203e".join([''] * (x_bounds[1] - x_bounds[0] + 4))) time.sleep(0.1) with open("high_score.dat", "w") as f: f.write(f"{h_score}\n") listener.stop() listener.join()