Init
Signed-off-by: Skylar "The Cobra" Widulski <cobra@vern.cc>
This commit is contained in:
commit
9a58087684
|
@ -0,0 +1,3 @@
|
|||
# snake.py
|
||||
|
||||
I made this a long time ago and thought it was lost, but when i was searching through my old phone's files, I found it.
|
|
@ -0,0 +1,363 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import curses
|
||||
from select import select, error
|
||||
from getopt import getopt, GetoptError
|
||||
from math import floor
|
||||
from subprocess import check_call
|
||||
from random import randint, choice
|
||||
from shlex import split
|
||||
from struct import unpack
|
||||
from time import sleep
|
||||
STDIN_FILENO = sys.stdin.fileno()
|
||||
|
||||
body=[]
|
||||
cherries=[]
|
||||
paused=False
|
||||
|
||||
snake_col=(255, 255, 255)
|
||||
cherry_col=(255, 0, 0)
|
||||
bg_col=(0, 0, 0)
|
||||
arg_cherry=1
|
||||
interval=0.1
|
||||
rainbow_snake=False
|
||||
rainbow_cherry=False
|
||||
rainbow_bg=False
|
||||
length=1
|
||||
grow=1
|
||||
growths=0
|
||||
should_grow = False
|
||||
die_to_self=True
|
||||
die_to_wall=True
|
||||
score = 0
|
||||
|
||||
def hex_to_rgb(hexa):
|
||||
try:
|
||||
return tuple(int(hexa.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
|
||||
except:
|
||||
_help()
|
||||
|
||||
def get_args():
|
||||
global arg_cherry
|
||||
global snake_col
|
||||
global bg_col
|
||||
global cherry_col
|
||||
global interval
|
||||
global rainbow_snake
|
||||
global rainbow_cherry
|
||||
global rainbow_bg
|
||||
global length
|
||||
global grow
|
||||
global die_to_self
|
||||
global die_to_wall
|
||||
try:
|
||||
opts, args = getopt(sys.argv[1:], 'hnwc:b:s:r:i:l:g:', ['cherries=', 'background=', 'background-color=', 'cherry-color=', 'snake=', 'snake-color=', 'interval=', 'length=', 'grow=', 'no-self-collision', 'no-wall-collision', 'help'])
|
||||
except GetoptError:
|
||||
_help()
|
||||
for opt, arg in opts:
|
||||
try:
|
||||
if opt in ("-c", "--cherries"):
|
||||
arg_cherry = int(arg)
|
||||
elif opt in ("-b", "--background", "--background-color"):
|
||||
if int(arg) == -1:
|
||||
rainbow_bg=True
|
||||
else:
|
||||
bg_col = hex_to_rgb(arg)
|
||||
elif opt in ("-r", "--cherry-color"):
|
||||
if int(arg) == -1:
|
||||
rainbow_cherry=True
|
||||
else:
|
||||
cherry_col = hex_to_rgb(arg)
|
||||
elif opt in ("-s", "--snake", "--snake-color"):
|
||||
if int(arg) == -1:
|
||||
rainbow_snake=True
|
||||
else:
|
||||
snake_col = hex_to_rgb(arg)
|
||||
elif opt in ("-i", "--interval"):
|
||||
interval = float(arg)
|
||||
elif opt in ("-l", "--length"):
|
||||
length = int(arg)
|
||||
elif opt in ("-g", "--grow"):
|
||||
grow = int(arg)
|
||||
elif opt in ("-n", "--no-self-collision"):
|
||||
die_to_self=False
|
||||
elif opt in ("-w", "--no-wall-collision"):
|
||||
die_to_wall=False
|
||||
elif opt in ('-h', '--help'):
|
||||
big_help()
|
||||
except ValueError:
|
||||
_help()
|
||||
|
||||
def cherry():
|
||||
global body
|
||||
global cherries
|
||||
used_spaces = body.copy()
|
||||
used_spaces.extend(cherries)
|
||||
lst = list(set(all_tuples)-set(used_spaces))
|
||||
if len(lst) > 0:
|
||||
return choice(lst)
|
||||
else:
|
||||
return (-1, -1)
|
||||
|
||||
def _help():
|
||||
try:
|
||||
curses.endwin()
|
||||
except:
|
||||
pass
|
||||
print("snake [OPTIONS...]", end='\r\n')
|
||||
exit()
|
||||
|
||||
def big_help():
|
||||
try:
|
||||
curses.endwin()
|
||||
except:
|
||||
pass
|
||||
print(
|
||||
"""python snake.py [OPTIONS...]
|
||||
|
||||
OPTIONS:
|
||||
-c INTEGER How many cherries will exist at once
|
||||
--cherries=
|
||||
|
||||
-b HEX Color of the background
|
||||
--background= --background-color=
|
||||
|
||||
-s HEX Color of the snake (-1 for random)
|
||||
--snake= --snake-color=
|
||||
|
||||
-r HEX Color of the cherry
|
||||
--cherry-color=
|
||||
|
||||
-i INTEGER How many seconds between movements
|
||||
--interval=
|
||||
|
||||
-l INTEGER Initial length of snake
|
||||
--length=
|
||||
|
||||
-g INTEGER How much to grow from cherries
|
||||
--grow=
|
||||
|
||||
-n Turn off collision with the snake's body
|
||||
--no-self-collision
|
||||
|
||||
-w Turn off collision with the walls
|
||||
--no-wall-collision
|
||||
|
||||
-h --help Show this page and quit
|
||||
|
||||
""", end='\r\n')
|
||||
exit()
|
||||
|
||||
def stop():
|
||||
print('\033[0m', end='')
|
||||
curses.curs_set(1)
|
||||
curses.endwin()
|
||||
print(f'Score: {score}', end='\r\n')
|
||||
exit()
|
||||
|
||||
def win():
|
||||
print('\033[0m', end='')
|
||||
curses.endwin()
|
||||
print('You win!', end='\r\n')
|
||||
exit()
|
||||
|
||||
def get_terminal_size():
|
||||
from platform import system
|
||||
current_os = system()
|
||||
tuple_xy = None
|
||||
if current_os == 'Windows':
|
||||
tuple_xy = _get_terminal_size_windows()
|
||||
if tuple_xy is None:
|
||||
tuple_xy = _get_terminal_size_tput()
|
||||
if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'):
|
||||
tuple_xy = _get_terminal_size_linux()
|
||||
if tuple_xy is None:
|
||||
print("default")
|
||||
tuple_xy = (80, 25)
|
||||
return tuple_xy
|
||||
|
||||
|
||||
def _get_terminal_size_windows():
|
||||
try:
|
||||
from ctypes import windll, create_string_buffer
|
||||
h = windll.kernel32.GetStdHandle(-12)
|
||||
csbi = create_string_buffer(22)
|
||||
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
|
||||
if res:
|
||||
(bufx, bufy, curx, cury, wattr,
|
||||
left, top, right, bottom,
|
||||
maxx, maxy) = unpack("hhhhHhhhhhh", csbi.raw)
|
||||
sizex = right - left + 1
|
||||
sizey = bottom - top + 1
|
||||
return sizex, sizey
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def _get_terminal_size_tput():
|
||||
try:
|
||||
cols = int(check_call(['tput', 'cols']))
|
||||
rows = int(check_call(['tput', 'lines']))
|
||||
return (cols, rows)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def _get_terminal_size_linux():
|
||||
def ioctl_GWINSZ(fd):
|
||||
try:
|
||||
from fcntl import ioctl
|
||||
from termios import TIOCGWINSZ
|
||||
cr = unpack('hh', ioctl(fd, TIOCGWINSZ, '1234'))
|
||||
return cr
|
||||
except:
|
||||
pass
|
||||
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
|
||||
if not cr:
|
||||
try:
|
||||
fd = os.open(os.ctermid(), os.O_RDONLY)
|
||||
cr = ioctl_GWINSZ(fd)
|
||||
os.close(fd)
|
||||
except:
|
||||
pass
|
||||
if not cr:
|
||||
try:
|
||||
cr = (os.environ['LINES'], os.environ['COLUMNS'])
|
||||
except:
|
||||
return None
|
||||
return int(cr[1]), int(cr[0])
|
||||
|
||||
def __select(iwtd, owtd, ewtd):
|
||||
while True:
|
||||
try:
|
||||
return select(iwtd, owtd, ewtd, 0)
|
||||
except error:
|
||||
err = sys.exc_info()[1]
|
||||
if err.args[0] == errno.EINTR:
|
||||
return([], [], [])
|
||||
else:
|
||||
raise
|
||||
|
||||
try:
|
||||
sx, sy = get_terminal_size()
|
||||
all_tuples = []
|
||||
for i in range(sx):
|
||||
for j in range(sy):
|
||||
all_tuples.append((i, j))
|
||||
direction = 0
|
||||
curses.initscr()
|
||||
curses.curs_set(0)
|
||||
get_args()
|
||||
for i in range(length):
|
||||
x,y = floor(sx/2), floor(sy/2)+i
|
||||
body.append((x,y))
|
||||
for i in range(arg_cherry):
|
||||
cherries.append((-1,-1))
|
||||
for i in range(len(cherries)):
|
||||
cherries[i] = cherry()
|
||||
while True:
|
||||
r, w, e = __select([STDIN_FILENO], [], [])
|
||||
if STDIN_FILENO in r:
|
||||
data=os.read(STDIN_FILENO, 1)
|
||||
if len(data) == 0:
|
||||
stop()
|
||||
if data[0] == 27:
|
||||
data=os.read(STDIN_FILENO, 1)
|
||||
if len(data) == 0:
|
||||
stop()
|
||||
if data[0] == 91:
|
||||
data=os.read(STDIN_FILENO, 1)
|
||||
if len(data) == 0:
|
||||
stop()
|
||||
if data[0] == 65 and (direction != 1 or len(body) == 1):
|
||||
direction = 0
|
||||
elif data[0] == 66 and (direction != 0 or len(body) == 1):
|
||||
direction = 1
|
||||
elif data[0] == 67 and (direction != 3 or len(body) == 1):
|
||||
direction = 2
|
||||
elif data[0] == 68 and (direction != 2 or len(body) == 1):
|
||||
direction = 3
|
||||
elif data[0] == 70:
|
||||
if paused:
|
||||
stop()
|
||||
elif data[0] == 72:
|
||||
paused = not paused
|
||||
elif data[0] in (119, 87):
|
||||
direction = 0
|
||||
elif data[0] in (115, 83):
|
||||
direction = 1
|
||||
elif data[0] in (100, 68):
|
||||
direction = 2
|
||||
elif data[0] in (97, 65):
|
||||
direction = 3
|
||||
elif data[0] in (101, 69):
|
||||
if paused:
|
||||
stop()
|
||||
elif data[0] in (112, 80):
|
||||
paused = not paused
|
||||
|
||||
if not paused:
|
||||
last = body[0]
|
||||
if direction == 0:
|
||||
body[0] = (body[0][0], body[0][1]-1)
|
||||
elif direction == 1:
|
||||
body[0] = (body[0][0], body[0][1]+1)
|
||||
elif direction == 2:
|
||||
body[0] = (body[0][0]+1, body[0][1])
|
||||
elif direction == 3:
|
||||
body[0] = (body[0][0]-1, body[0][1])
|
||||
for i in range(len(body)-1):
|
||||
temp = body[i+1]
|
||||
body[i+1] = last
|
||||
last = temp
|
||||
|
||||
if body[0] in cherries:
|
||||
cherries[cherries.index(body[0])] = cherry()
|
||||
should_grow = True
|
||||
score += 1
|
||||
if growths == grow:
|
||||
growths = 0
|
||||
should_grow = False
|
||||
elif should_grow:
|
||||
new = (body[-1][0], body[-1][1])
|
||||
body.append(new)
|
||||
growths += 1
|
||||
|
||||
if body.count(body[0]) > 1 and len(body) > 2 and die_to_self:
|
||||
stop()
|
||||
|
||||
if body[0][0] >= sx or body[0][0] < 0 or body[0][1] >= sy-1 or body[0][1] < 0:
|
||||
if die_to_wall:
|
||||
stop()
|
||||
else:
|
||||
body[0] = (body[0][0] % sx, body[0][1] % sy)
|
||||
|
||||
for j in range(sy-1):
|
||||
print(f'\033[{j+1};0H', end='')
|
||||
for i in range(sx):
|
||||
if (i, j) in body:
|
||||
if rainbow_snake:
|
||||
snake_col = (randint(0,256), randint(0,256), randint(0,256))
|
||||
print(f'\033[48;2;{snake_col[0]};{snake_col[1]};{snake_col[2]}m ', end='')
|
||||
elif (i, j) in cherries:
|
||||
if rainbow_cherry:
|
||||
cherry_col = (randint(0,256), randint(0,256), randint(0,256))
|
||||
print(f'\033[48;2;{cherry_col[0]};{cherry_col[1]};{cherry_col[2]}m ', end='')
|
||||
else:
|
||||
if rainbow_bg:
|
||||
bg_col = (randint(0,256), randint(0,256), randint(0,256))
|
||||
print(f'\033[48;2;{bg_col[0]};{bg_col[1]};{bg_col[2]}m ', end='')
|
||||
print(f'\033[0mScore: {score}', end='')
|
||||
if not paused:
|
||||
print(f'\033[{sy+1};{sx-5}H ', end='')
|
||||
else:
|
||||
print(f'\033[{sy+1};{sx-5}HPaused', end='')
|
||||
if list(set(all_tuples)-set(body)) == []:
|
||||
win()
|
||||
if interval > 0:
|
||||
sleep(interval)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
stop()
|
Loading…
Reference in New Issue