diff --git a/Tetris.py b/Tetris.py index 9956eef..dc55366 100644 --- a/Tetris.py +++ b/Tetris.py @@ -1,5 +1,6 @@ import sys import pygame + from util.ConfigurationManager import ConfigurationManager from util.PieceGenerator import PieceGenerator from entity.Well import Well @@ -15,7 +16,7 @@ class Tetris: self.well = None self.current_piece = None - def initialize(self): + def initialize(self) -> None: pygame.init() win_width = ConfigurationManager.configuration["window"]["width"] @@ -34,7 +35,7 @@ class Tetris: pygame.display.set_icon(loaded_icon) # gets called from the games main loop - def update(self): + def update(self) -> None: # TODO write not initialized exception self.clock.tick(self.fps) @@ -58,8 +59,10 @@ class Tetris: self.current_piece.move((0, self.tile_size)) if event.key == pygame.K_z: self.__generate_piece((300, 100)) + if event.key == pygame.K_x: + self.current_piece.revert() - def draw(self): + def draw(self) -> None: # TODO write not initialized exception # draw window bg diff --git a/entity/Entity.py b/entity/Entity.py new file mode 100644 index 0000000..e1ec1af --- /dev/null +++ b/entity/Entity.py @@ -0,0 +1,14 @@ +import pygame + +class Entity: + def __init__(self): + pass + + def update(self) -> None: + pass + + def draw(self, surface: pygame.Surface) -> None: + pass + + def collide(self, entity) -> bool: + pass diff --git a/entity/Piece.py b/entity/Piece.py index a6217c3..7cf5b82 100644 --- a/entity/Piece.py +++ b/entity/Piece.py @@ -1,19 +1,27 @@ +from typing import List, Tuple import pygame +import copy +from entity.Entity import Entity from util.ConfigurationManager import ConfigurationManager ''' For information on the Tetris piece Tetromino go here: https://tetris.fandom.com/wiki/Tetromino ''' -class Piece: # TODO game objects base class / interface? +class Piece(Entity): - def __init__(self, shape, position, color): + def __init__(self, shape: Tuple, position: Tuple, color: str): + super().__init__() + self.color = color self.points = self.__get_points(shape, position) self.center = self.__get_center(shape, position) - def draw(self, surface): + self.previous_points = None + self.previous_center = None + + def draw(self, surface: pygame.Surface) -> None: tile_size = ConfigurationManager.configuration["engine"]["tile-size"] hex_color = ConfigurationManager.configuration["color"]["border"] # TODO should abstract out color call? @@ -24,7 +32,10 @@ class Piece: # TODO game objects base class / interface? pygame.draw.polygon(surface, base_color, sub_points, 0) pygame.draw.polygon(surface, border_color, sub_points, max(tile_size // 6, 1)) - def move(self, vector): + def move(self, vector: Tuple) -> None: + self.previous_points = copy.deepcopy(self.points) + self.previous_center = copy.deepcopy(self.center) + self.center[0] += vector[0] self.center[1] += vector[1] @@ -37,7 +48,10 @@ class Piece: # TODO game objects base class / interface? For more information on a rotation of a piece go here: https://gamedev.stackexchange.com/questions/17974/how-to-rotate-blocks-in-tetris ''' - def rotate(self): + def rotate(self) -> None: + self.previous_points = copy.deepcopy(self.points) + self.previous_center = copy.deepcopy(self.center) + for sub_points in self.points: for point in sub_points: h = point[0] - self.center[0] @@ -46,11 +60,13 @@ class Piece: # TODO game objects base class / interface? point[0] = (k * -1) + self.center[0] point[1] = h + self.center[1] - def colliding(object): - pass + def revert(self) -> None: + if self.previous_points and self.previous_center: + self.points = self.previous_points + self.center = self.previous_center - def __get_points(self, shape, position): - tile_size = ConfigurationManager.configuration["engine"]["tile-size"] + def __get_points(self, shape: Tuple, position: Tuple) -> List: + tile_size = ConfigurationManager.configuration["engine"]["tile-size"] points = [] for square in shape[:-1]: @@ -62,7 +78,7 @@ class Piece: # TODO game objects base class / interface? return points - def __get_center(self, shape, position): + def __get_center(self, shape: Tuple, position: Tuple) -> List: tile_size = ConfigurationManager.configuration["engine"]["tile-size"] center = shape[-1] diff --git a/entity/Well.py b/entity/Well.py index 7bb44f9..f27798c 100644 --- a/entity/Well.py +++ b/entity/Well.py @@ -1,23 +1,25 @@ +from typing import List, Tuple import pygame +from entity.Entity import Entity from util.ConfigurationManager import ConfigurationManager -class Well: # TODO game objects base class / interface? +class Well(Entity): WIDTH = 10 # standard tetris well width, should not be changed HEIGHT = 20 # standard tetris well height, should not be changed - def __init__(self, position): + def __init__(self, position: Tuple): self.points = self.__get_points(position) - def draw(self, surface): + def draw(self, surface: pygame.Surface) -> None: well_color_hex = ConfigurationManager.configuration["color"]["border"] # TODO Should abstract out color call? well_color = pygame.Color(well_color_hex) for sub_points in self.points: pygame.draw.polygon(surface, well_color, sub_points, 0) - def __get_points(self, position): + def __get_points(self, position: Tuple) -> List: tile_size = ConfigurationManager.configuration["engine"]["tile-size"] shape = [] diff --git a/main.py b/main.py index e1c78c9..421e3e2 100644 --- a/main.py +++ b/main.py @@ -4,10 +4,12 @@ https://tetris.com/play-tetris ''' +# TODO review imports to make sure it is being done correctly + from Tetris import Tetris from util.ConfigurationManager import ConfigurationManager -def main(): +def main() -> None: ConfigurationManager.load() tetris = Tetris() diff --git a/util/ConfigurationManager.py b/util/ConfigurationManager.py index a0f6105..83b143d 100644 --- a/util/ConfigurationManager.py +++ b/util/ConfigurationManager.py @@ -8,6 +8,6 @@ class ConfigurationManager: configuration = [] @classmethod - def load(cls): + def load(cls) -> None: with open(CONFIG_FILE_LOCATION, "r") as yaml_file: cls.configuration = yaml.safe_load(yaml_file) \ No newline at end of file diff --git a/util/PieceGenerator.py b/util/PieceGenerator.py index c347e00..d6d0ace 100644 --- a/util/PieceGenerator.py +++ b/util/PieceGenerator.py @@ -1,3 +1,4 @@ +from typing import Tuple import random from entity.Piece import Piece @@ -11,20 +12,20 @@ class PieceGenerator: __bucket = [] @classmethod - def get_piece(cls, position): + def get_piece(cls, position: Tuple) -> Piece: if len(cls.__bucket) == 0: cls.__generate_bucket() return Piece(cls.__get_piece_shape(cls.__bucket.pop()), position, cls.__get_piece_color()) @classmethod - def __generate_bucket(cls): + def __generate_bucket(cls) -> None: piece_types = list(range(7)) while len(cls.__bucket) != 7: random_number = random.randint(0, 6 - len(cls.__bucket)) cls.__bucket.append(piece_types.pop(random_number)) - def __get_piece_shape(piece_number): + def __get_piece_shape(piece_number: int) -> Tuple: if piece_number == 0: return Piece.I_SHAPE if piece_number == 1: @@ -42,6 +43,6 @@ class PieceGenerator: return None - def __get_piece_color(): + def __get_piece_color() -> str: random_number = random.randint(1, 3) return ConfigurationManager.configuration["color"]["base-" + str(random_number)]