Compare commits

..

No commits in common. "main" and "1" have entirely different histories.
main ... 1

9 changed files with 69 additions and 140 deletions

View File

@ -5,4 +5,3 @@ Default keys:
-- --
W A S D - move W A S D - move
Q - quit Q - quit
P - pause

View File

@ -4,8 +4,9 @@ from settings import *
class Food(Point): class Food(Point):
def __init__(self, x, y): def __init__(self, x, y, pl):
Point.__init__(self, x, y) Point.__init__(self, x, y)
self.pl = pl
def generate_new(self) -> None: def generate_new(self) -> None:
self.x = randint(0, WIDTH - 1) self.x = randint(0, WIDTH - 1)

View File

@ -9,10 +9,10 @@ if platform == "win32":
class COORDSET(Structure): class COORDSET(Structure):
_fields_ = [("X", c_long), ("Y", c_long)] _fields_ = [("X", c_long), ("Y", c_long)]
def set_cursor_position(x: int, y: int) -> None: def _set_cursor_position(x: int, y: int) -> None:
windll.kernel32.SetConsoleCursorPosition(STDHANDLE, COORDSET(x, y)) windll.kernel32.SetConsoleCursorPosition(STDHANDLE, COORDSET(x, y))
else: else:
def set_cursor_position(x: int, y: int) -> None: def _set_cursor_position(x: int, y: int) -> None:
print(f"\033[{x};{y}H") print(f"\033[{x};{y}H")
@ -23,20 +23,14 @@ class Frame:
self.matrix = [[SPACE] * width for line in range(height)] self.matrix = [[SPACE] * width for line in range(height)]
def __str__(self) -> str: def __str__(self) -> str:
return ( out_string = f"Width:\n {self.width}\n"
f"Width:\n {self.width}\n" out_string += f"Height:\n {self.height}\n"
f"Height:\n {self.height}" return out_string
)
def draw( def draw(
self, self, x: int, y: int,
x: int,
y: int,
value: int = WALL, value: int = WALL,
width: int = 1, width: int = 1, height: int = 1
height: int = 1
) -> None: ) -> None:
if not isinstance(value, int): if not isinstance(value, int):
raise TypeError("Value must be int") raise TypeError("Value must be int")
@ -46,29 +40,27 @@ class Frame:
self.matrix[y + line][x + column] = value self.matrix[y + line][x + column] = value
def show(self) -> None: def show(self) -> None:
set_cursor_position(0, 0) _set_cursor_position(0, 0)
out_string = f"{WALL_COLOR}{'' * (self.width * 2)}{RESET_COLOR}\n" out_string = f"{'' * (self.width * 2)}\n"
for line in self.matrix: for line in self.matrix:
to_str = '' to_str = ''
to_str += f'{WALL_COLOR}{RESET_COLOR}' to_str += ''
for elem in line: for elem in line:
if elem == SPACE: if elem == SPACE:
to_str += TT_SPACE to_str += " "
elif elem == WALL: elif elem == WALL:
to_str += TT_WALL to_str += "██"
elif elem == FOOD: elif elem == FOOD:
to_str += TT_FOOD to_str += "@@"
elif elem == WALL_FOOD: elif elem == WALL_FOOD:
to_str += TT_WALL_FOOD to_str += "@█"
elif elem == HEAD: to_str += '\n'
to_str += TT_HEAD
to_str += f'{WALL_COLOR}{RESET_COLOR}\n'
out_string += to_str out_string += to_str
out_string += f"{WALL_COLOR}{'' * (self.width * 2)}{RESET_COLOR}" out_string += f"{'' * (self.width * 2)}"
print(out_string) print(out_string)

62
main.py
View File

@ -1,80 +1,46 @@
# from frame import Frame
from settings import * from settings import *
from player import Player from player import Player
import keyboard as kb import keyboard as kb
from out import Out from out import Out
from os import system from os import system
from time import sleep, time
class Game: class Game:
def __init__(self) -> None: def __init__(self) -> None:
self.running = True self.running = True
self.is_pause = False
self.pl = Player() self.pl = Player()
self.out = Out(self.pl) self.out = Out()
kb.add_hotkey(QUIT_BUTTON, self.stop_game) kb.add_hotkey(QUIT_BUTTON, self.stop_game)
kb.add_hotkey(PAUSE_BUTTON, self.switch_pause) kb.add_hotkey(LEFT_BUTTON, self.pl.left)
kb.add_hotkey( kb.add_hotkey(RIGHT_BUTTON, self.pl.right)
LEFT_BUTTON, kb.add_hotkey(UP_BUTTON, self.pl.up)
self.pl.left, kb.add_hotkey(DOWN_BUTTON, self.pl.down)
args=[self]
)
kb.add_hotkey(
RIGHT_BUTTON,
self.pl.right,
args=[self]
)
kb.add_hotkey(
UP_BUTTON,
self.pl.up,
args=[self]
)
kb.add_hotkey(
DOWN_BUTTON,
self.pl.down,
args=[self]
)
def switch_pause(self) -> None:
self.is_pause = not self.is_pause
def stop_game(self) -> None: def stop_game(self) -> None:
if not self.is_pause:
self.running = False self.running = False
def update(self) -> None:
pass
def output(self) -> None:
pass
def play(self) -> None: def play(self) -> None:
system("clear||cls") system("clear||cls")
print()
start_time = time()
different_between_time = 1 / FPS
while self.running: while self.running:
try: try:
sleep(1 / FPS - different_between_time)
start_time = time()
if not self.is_pause:
self.pl.input()
self.pl.update() self.pl.update()
self.out.draw() self.out.draw(self.pl)
end_time = time()
different_between_time = start_time - end_time
except IndexError as e: except IndexError as e:
self.running = False self.running = False
print(e) print(e)
except KeyboardInterrupt:
return
input("Press enter to leave from game.\n")
def main() -> None: def main() -> None:
game = Game() Game().play()
game.play()
if __name__ == '__main__': if __name__ == '__main__':

19
out.py
View File

@ -4,28 +4,26 @@ from frame import Frame
class Out: class Out:
def __init__(self, pl: Player) -> None: def __init__(self) -> None:
self.width = WIDTH self.width = WIDTH
self.height = HEIGHT self.height = HEIGHT
self.pl = pl self.fps = FPS
def draw(self) -> None: def draw(self, pl: Player) -> None:
frame = Frame(self.width, self.height) frame = Frame(self.width, self.height)
pl = self.pl
for point in pl.body: for point in pl.body:
if point.x < 0 or point.y < 0:
raise IndexError("Snake has collision with walls")
elif point.x >= WIDTH or point.y >= HEIGHT:
raise IndexError("Snake has collision with walls")
frame.draw( frame.draw(
x=point.x, y=point.y, x=point.x, y=point.y,
value=WALL, value=WALL,
width=1, height=1 width=1, height=1
) )
frame.draw(
x=pl.body[-1].x, y=pl.body[-1].y,
value=HEAD,
width=1, height=1
)
if frame.see(pl.food.x, pl.food.y) == WALL: if frame.see(pl.food.x, pl.food.y) == WALL:
frame.draw( frame.draw(
x=pl.food.x, y=pl.food.y, x=pl.food.x, y=pl.food.y,
@ -38,4 +36,3 @@ class Out:
) )
frame.show() frame.show()
print(f"Score: {pl.score}")

View File

@ -1,62 +1,50 @@
from settings import * from settings import *
from point import Point from point import Point
from food import Food from food import Food
from time import sleep
from itertools import permutations
class Player: class Player:
def __init__(self) -> None: def __init__(self) -> None:
self.start_direciton = MAIN_DIRECTION
self.direction = MAIN_DIRECTION self.direction = MAIN_DIRECTION
self.body = [Point(MAIN_X, MAIN_Y)] self.body = [Point(MAIN_X, MAIN_Y)]
self.food = Food(0, 0) self.food = Food(0, 0, self)
self.food.generate_new() self.food.generate_new()
self.score = 1 def update(self) -> None:
sleep(1 / FPS)
def input(self) -> None:
if self.direction == D_UP: if self.direction == D_UP:
# self.body[0].y -= 1
self.body.append(Point(self.body[-1].x, self.body[-1].y - 1)) self.body.append(Point(self.body[-1].x, self.body[-1].y - 1))
elif self.direction == D_DOWN: elif self.direction == D_DOWN:
# self.body[0].y += 1
self.body.append(Point(self.body[-1].x, self.body[-1].y + 1)) self.body.append(Point(self.body[-1].x, self.body[-1].y + 1))
elif self.direction == D_LEFT: elif self.direction == D_LEFT:
# self.body[0].x -= 1
self.body.append(Point(self.body[-1].x - 1, self.body[-1].y)) self.body.append(Point(self.body[-1].x - 1, self.body[-1].y))
elif self.direction == D_RIGHT: elif self.direction == D_RIGHT:
# self.body[0].x += 1
self.body.append(Point(self.body[-1].x + 1, self.body[-1].y)) self.body.append(Point(self.body[-1].x + 1, self.body[-1].y))
def _check_collision(body: list[Point]) -> None:
for point in body:
if point.x < 0 or point.y < 0:
raise IndexError("Snake has collision with walls")
elif point.x >= WIDTH or point.y >= HEIGHT:
raise IndexError("Snake has collision with walls")
if len(set(body)) != len(body):
raise IndexError("Player has collision with self")
def update(self) -> None:
self.start_direction = self.direction
if self.body[-1] == self.food: if self.body[-1] == self.food:
self.food.generate_new() self.food.generate_new()
self.score += 1
else: else:
self.body.pop(0) self.body.pop(0)
Player._check_collision(self.body) if len(set(self.body)) != len(self.body):
raise IndexError("Player has collision with self")
def left(self, game) -> None: def left(self) -> None:
if not game.is_pause and self.start_direction != D_RIGHT:
self.direction = D_LEFT self.direction = D_LEFT
def right(self, game) -> None: def right(self) -> None:
if not game.is_pause and self.start_direction != D_LEFT:
self.direction = D_RIGHT self.direction = D_RIGHT
def up(self, game) -> None: def up(self) -> None:
if not game.is_pause and self.start_direction != D_DOWN:
self.direction = D_UP self.direction = D_UP
def down(self, game) -> None: def down(self) -> None:
if not game.is_pause and self.start_direction != D_UP:
self.direction = D_DOWN self.direction = D_DOWN

View File

@ -4,15 +4,15 @@ class Point:
self.y = y self.y = y
def __eq__(self, other) -> bool: def __eq__(self, other) -> bool:
if not isinstance(other, Point): if isinstance(other, Point):
return False
if self.x == other.x and self.y == other.y: if self.x == other.x and self.y == other.y:
return True return True
else: else:
return False return False
else:
raise TypeError("You can compare only Point with Point")
def __hash__(self) -> int: def __hash__(self) -> None:
return int(f"{abs(self.x)}000{abs(self.y)}") return int(f"{abs(self.x)}000{abs(self.y)}")
def __str__(self) -> str: def __str__(self) -> str:

View File

@ -1 +0,0 @@
keyboard==0.13.5

View File

@ -2,12 +2,9 @@
WIDTH = 20 WIDTH = 20
HEIGHT = 20 HEIGHT = 20
FPS = 5 FPS = 5
WALL_COLOR = "\u001b[31m"
RESET_COLOR = "\u001b[0m"
# Buttons # Buttons
QUIT_BUTTON = 'q' QUIT_BUTTON = 'q'
PAUSE_BUTTON = 'p'
LEFT_BUTTON = 'a' LEFT_BUTTON = 'a'
RIGHT_BUTTON = 'd' RIGHT_BUTTON = 'd'
UP_BUTTON = 'w' UP_BUTTON = 'w'
@ -27,13 +24,3 @@ SPACE = 0
WALL = 1 WALL = 1
FOOD = 2 FOOD = 2
WALL_FOOD = 3 WALL_FOOD = 3
HEAD = 4
TT_SPACE = " "
TT_WALL = "\u001b[34m{}\u001b[0m".format("██")
TT_FOOD = "\u001b[33m{}\u001b[0m".format("██")
TT_WALL_FOOD = "\u001b[32m{}\u001b[0m".format("██")
TT_HEAD = "\u001b[36m{}\u001b[0m".format("██")
# Globals
is_pause = False