153 lines
4.7 KiB
Python
153 lines
4.7 KiB
Python
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()
|