Created
August 25, 2020 18:52
-
-
Save dolohow/3ffc710ebe17f2f484542a33dc9f7444 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 curses | |
import pdb | |
import random | |
import time | |
from curses import wrapper | |
GAME_BOARD_SIZE = (20, 20) | |
def debug(stdscr, data): | |
stdscr.addstr(25, 0, str(data)) | |
class GameOver(Exception): | |
pass | |
class Point(): | |
def __init__(self, y, x): | |
self.y = y | |
self.x = x | |
def __add__(self, other): | |
return Point(self.y + other.y, self.x + other.x) | |
def __eq__(self, other): | |
return self.x == other.x and self.y == other.y | |
def __repr__(self): | |
return f'({self.y}, {self.x})' | |
class Figure(): | |
STATUS_NEW = 1 | |
STATUS_MOVED = 2 | |
def __init__(self, stdscr, points): | |
self.stdscr = stdscr | |
self.points = points | |
self.current_position = Point(0, 0) | |
self.status = self.STATUS_NEW | |
def draw(self, starting_position): | |
self.current_position = starting_position | |
for point in self.points: | |
self.stdscr.addstr(point.y + starting_position.y, | |
point.x + starting_position.x, '*') | |
def clear(self): | |
for p in self.points: | |
self.stdscr.addstr(p.y + self.current_position.y, | |
p.x + self.current_position.x, ' ') | |
def try_rotate(self, clockwise=True): | |
points = [] | |
for point in self.points: | |
if clockwise: | |
x = -point.y + self.current_position.x | |
y = point.x + self.current_position.y | |
else: | |
x = point.y + self.current_position.x | |
y = -point.x + self.current_position.y | |
points.append((Point(y, x))) | |
return Figure(self.stdscr, points) | |
def rotate(self, clockwise=True): | |
self.clear() | |
for point in self.points: | |
tmp = point.x | |
if clockwise: | |
point.x = -point.y | |
point.y = tmp | |
else: | |
point.x = point.y | |
point.y = -tmp | |
self.draw(self.current_position) | |
def move(self, point): | |
self.clear() | |
self.current_position += point | |
self.draw(self.current_position) | |
def move_right(self): | |
self.move(Point(0, 1)) | |
def move_left(self): | |
self.move(Point(0, -1)) | |
def move_down(self): | |
self.move(Point(1, 0)) | |
def get_current_position(self): | |
return [point + self.current_position for point in self.points] | |
def calculate_width(self): | |
width = 0 | |
for point in self.points: | |
if point.x > width: | |
width = point.x | |
return width | |
class Board(): | |
FIGURES = ( | |
(Point(0, 1), Point(1, 1), Point(2, 0), Point(2, 1)), | |
(Point(0, 0), Point(1, 0), Point(2, 0), Point(2, 1)), | |
(Point(0, 0), Point(0, 1), Point(1, 0), Point(1, 1)), | |
(Point(0, 0), Point(0, 1), Point(0, 2), Point(0, 3)), | |
(Point(0, 1), Point(1, 0), Point(1, 1), Point(2, 0)), | |
) | |
def __init__(self, stdscr): | |
self.stdscr = stdscr | |
self.figures_spawned = [] | |
def initialize(self): | |
for y in range(0, GAME_BOARD_SIZE[0]): | |
self.stdscr.addstr(y, 0, '*') | |
self.stdscr.addstr(y, GAME_BOARD_SIZE[0] + 1, '*') | |
for x in range(0, GAME_BOARD_SIZE[1] + 2): | |
self.stdscr.addstr(GAME_BOARD_SIZE[1], x, '*') | |
def draw_new_figure(self): | |
figure = Figure(self.stdscr, random.choice(self.FIGURES)) | |
if self.will_figure_overlap(figure, Point(0, 0)): | |
raise GameOver | |
figure.draw(Point(0, random.randint( | |
1, GAME_BOARD_SIZE[1] - figure.calculate_width()))) | |
return figure | |
def will_figure_overlap(self, new, direction): | |
current_position = new.get_current_position() | |
figures = [ | |
figure_pos for spawned in self.figures_spawned for figure_pos in spawned.get_current_position()] | |
for point in current_position: | |
if point + direction in figures: | |
return True | |
return False | |
def will_figure_touch_right_border(self, figure): | |
for point in figure.get_current_position(): | |
if point.x == GAME_BOARD_SIZE[1]: | |
return True | |
return False | |
def will_figure_touch_left_border(self, figure): | |
for point in figure.get_current_position(): | |
if point.x == 1: | |
return True | |
return False | |
def will_figure_touch_bottom(self, figure): | |
for point in figure.get_current_position(): | |
if point.y + 1 == GAME_BOARD_SIZE[0]: | |
return True | |
return False | |
def will_figure_touch_top(self, figure): | |
for point in figure.get_current_position(): | |
if point.y < 0: | |
return True | |
return False | |
def move_figure_down(self, figure): | |
if self.will_figure_touch_bottom(figure) or self.will_figure_overlap(figure, Point(1, 0)): | |
self.figures_spawned.append(figure) | |
return False | |
figure.move_down() | |
return True | |
def move_figure_right(self, figure): | |
if self.will_figure_touch_right_border(figure) or self.will_figure_overlap(figure, Point(0, 1)): | |
return False | |
figure.move_right() | |
return True | |
def move_figure_left(self, figure): | |
if self.will_figure_touch_left_border(figure) or self.will_figure_overlap(figure, Point(0, -1)): | |
return False | |
figure.move_left() | |
return True | |
def rotate_figure(self, figure, clockwise=True): | |
new_position = figure.try_rotate(clockwise) | |
if self.will_figure_overlap(new_position, Point(0, 0)): | |
return | |
if (self.will_figure_touch_top(new_position) or | |
self.will_figure_touch_left_border(new_position) or | |
self.will_figure_touch_right_border(new_position)): | |
return | |
figure.rotate(clockwise) | |
def start(stdscr): | |
board = Board(stdscr) | |
board.initialize() | |
figure = board.draw_new_figure() | |
stdscr.refresh() | |
while True: | |
key = stdscr.getkey() | |
if key == 's': | |
if board.rotate_figure(figure, clockwise=True) and not board.move_figure_down(figure): | |
figure = board.draw_new_figure() | |
if key == 'w': | |
if board.rotate_figure(figure, clockwise=False) and not board.move_figure_down(figure): | |
figure = board.draw_new_figure() | |
if key == 'd': | |
if board.move_figure_right(figure) and not board.move_figure_down(figure): | |
figure = board.draw_new_figure() | |
if key == 'a': | |
if board.move_figure_left(figure) and not board.move_figure_down(figure): | |
figure = board.draw_new_figure() | |
stdscr.refresh() | |
def main(stdscr): | |
stdscr.clear() | |
start(stdscr) | |
stdscr.refresh() | |
wrapper(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment