Basic tetris example
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Alfred 51fb863eab Properly center position 5 months ago
.gitignore A first version for the game 5 months ago
README.md Add the game skeleton to the README 5 months ago
tetris.py Properly center position 5 months ago

README.md

Tetris

Game skeleton

import pygame
from random import choice
import sys


class Tile:
    def __init__(self, shape):
        self.shape = shape

    def rotate_left(self):
        updated_shape = []
        for line in range(len(self.shape[0])):
            new_line = []
            for column in reversed(range(len(self.shape))):
                new_line.append(self.shape[column][line])
            updated_shape.append(new_line)
        self.shape = updated_shape

    def rotate_right(self):
        updated_shape = []
        for line in reversed(range(len(self.shape[0]))):
            new_line = []
            for column in range(len(self.shape)):
                new_line.append(self.shape[column][line])
            updated_shape.append(new_line)
        self.shape = updated_shape


class Game:
    def __init__(self, win_size, grid_size):
    	"""
    	- win_size: Game window size
    	- grid_size: Numbers of blocks per columns and rows
    	- block_size: Given a window size and a grid size, is the block size
    	- board: Game board values
    	- tiles: List with all game tiles
    	- current_tile: This is the current active tile in the game
    	- current_position: Current tile position in the board
    	- display: PyGame display where performing all the drawing actions
    	- game_over: Flag that indicates if the game has ended
    	"""
        self.win_size = win_size
        self.grid_size = grid_size
        self.block_size = (win_size[0] / grid_size[0], win_size[1] / grid_size[1])
        self.board = []
        self.tiles = [
            Tile(shape=[[1, 0], [1, 0], [1, 1]]),
            Tile(shape=[[0, 2], [0, 2], [2, 2]]),
            Tile(shape=[[3], [3], [3], [3]]),
            Tile(shape=[[4, 4], [4, 4]]),
            Tile(shape=[[5, 5, 0], [0, 5, 5]]),
            Tile(shape=[[0, 6, 6], [6, 6, 0]]),
            Tile(shape=[[0, 7, 0], [7, 7, 7]])
        ]
        self.current_tile = None
        self.current_position = [0, 0]
        self.display = None
        self.game_over = False

    def initialize(self):
    	"""
    	Initializes the game. First removes the game over flag, then cleans the board, and obtains
    	a new tile
    	"""
        self.game_over = False
        self.board = [[0 for _ in range(self.grid_size[0])] for _ in range(self.grid_size[1])]
        self.next_tile()

    def next_tile(self):
    	"""
    	Obtains a new tile initializing its position
    	"""
        self.current_position = [int(self.grid_size[0] / 2), 0]
        self.current_tile = choice(self.tiles)

    def draw_block(self, x, y, num_color):
    	"""
    	Given an x, y position and a num color, draws 
    	"""
        if num_color == 0:
            return

        color = [
            None,
            pygame.Color('salmon'),
            pygame.Color('pink'),
            pygame.Color('orange'),
            pygame.Color('purple'),
            pygame.Color('tomato'),
            pygame.Color('orchid'),
            pygame.Color('lavender')
        ]
        right, top = self.block_size[0] * x, self.block_size[1] * y
        width, height = self.block_size[0], self.block_size[1]

        pygame.draw.rect(self.display, color[num_color], (right, top, width, height))

    def draw_board(self):
    	"""
    	Draws board blocks
    	"""
        pass

    def draw_current_tile(self):
        """
        Draws those blocks corresponding to the current tile
        """
        pass

    def draw(self):
    	"""
    	Draws the current state of the game. For this, it first cleans the windows, draws the board, and 
    	on the last step draws the current tile
    	"""
        self.display.fill(pygame.Color('black'))
        self.draw_board()
        self.draw_current_tile()

    def handle_events(self):
    	"""
    	Handles those game events given by PyGame
    	"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT and not self.game_over and self.can_move(move_x=-1, move_y=0):
                    self.current_position[0] -= 1
                elif event.key == pygame.K_RIGHT and not self.game_over and self.can_move(move_x=1, move_y=0):
                    self.current_position[0] += 1
                elif event.key == pygame.K_q:
                    self.current_tile.rotate_left()
                elif event.key == pygame.K_w:
                    self.current_tile.rotate_right()
                elif event.key == pygame.K_SPACE:
                    self.initialize()
                elif event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

    def can_move(self, move_x, move_y):
    	"""
    	Returns True if there is no obstacle and no border in the current position adding the indicated move
    	"""
    	pass

    def add_current_tile_to_board(self):
        """
        Changes the board matrix adding the current tile values
        """
        pass

    def update_lines(self):
        """
        Finds how many lines have been made and removes them from the board
        """
        pass

    def update_tile(self):
    	"""
    	Performs those actions corresponding to the current tile into the current iteration.
    	First checks if the current tile can be move to the next line. If so it moves it.
    	If not, then it adds their values to the board, updates how many lines were achieved, 
    	and obtains the next tile. If this new tile cannot move at this moment, then this is 
    	the game over.
    	"""
        if self.can_move(0, 1):
            self.current_position[1] += 1
        else:
            self.add_current_tile_to_board()
            self.update_lines()
            self.next_tile()
            self.game_over = not self.can_move(0, 0)

    def update(self):
    	"""
    	Represents a game iteration (event handling, tile movement, and drawing)
    	"""
        self.handle_events()
        if not self.game_over:
            self.update_tile()
        self.draw()
        pygame.display.update()

    def start(self):
    	"""
    	Launches the game, initializing its values and performing the game loop.
    	"""
        pygame.init()
        self.display = pygame.display.set_mode(self.win_size, 0, 32)
        clock = pygame.time.Clock()

        self.initialize()
        while True:
            self.update()
            clock.tick(3)


if __name__ == '__main__':
    game = Game(win_size=(450, 900), grid_size=(10, 20))
    game.start()