Share your repls and programming experiences

← Back to all posts
Tetris in python Special thanks to @coder100 @PattanAhmed and @Sixbeeps for helping!!
codewithmenow (2)

import pygame
import random

"""
10 x 20 square grid
shapes: S, Z, I, O, J, L, T
represented in order by 0 - 6
"""

pygame.font.init()

GLOBALS VARS

s_width = 800
s_height = 700
play_width = 300 # meaning 300 // 10 = 30 width per block
play_height = 600 # meaning 600 // 20 = 20 height per blo ck
block_size = 30

top_left_x = (s_width - play_width) // 2
top_left_y = s_height - play_height

SHAPE FORMATS

S = [['.....',
'.....',
'..00.',
'.00..',
'.....'],
['.....',
'..0..',
'..00.',
'...0.',
'.....']]

Z = [['.....',
'.....',
'.00..',
'..00.',
'.....'],
['.....',
'..0..',
'.00..',
'.0...',
'.....']]

I = [['..0..',
'..0..',
'..0..',
'..0..',
'.....'],
['.....',
'0000.',
'.....',
'.....',
'.....']]

O = [['.....',
'.....',
'.00..',
'.00..',
'.....']]

J = [['.....',
'.0...',
'.000.',
'.....',
'.....'],
['.....',
'..00.',
'..0..',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'...0.',
'.....'],
['.....',
'..0..',
'..0..',
'.00..',
'.....']]

L = [['.....',
'...0.',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..0..',
'..00.',
'.....'],
['.....',
'.....',
'.000.',
'.0...',
'.....'],
['.....',
'.00..',
'..0..',
'..0..',
'.....']]

T = [['.....',
'..0..',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..00.',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'..0..',
'.....'],
['.....',
'..0..',
'.00..',
'..0..',
'.....']]

shapes = [S, Z, I, O, J, L, T]
shape_colors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)]

index 0 - 6 represent shape

class Piece(object):
rows = 20 # y
columns = 10 # x

def __init__(self, column, row, shape):
    self.x = column
    self.y = row
    self.shape = shape
    self.color = shape_colors[shapes.index(shape)]
    self.rotation = 0  # number from 0-3

def create_grid(locked_positions={}):
grid = [[(0,0,0) for x in range(10)] for x in range(20)]

for i in range(len(grid)):
    for j in range(len(grid[i])):
        if (j,i) in locked_positions:
            c = locked_positions[(j,i)]
            grid[i][j] = c
return grid

def convert_shape_format(shape):
positions = []
format = shape.shape[shape.rotation % len(shape.shape)]

for i, line in enumerate(format):
    row = list(line)
    for j, column in enumerate(row):
        if column == '0':
            positions.append((shape.x + j, shape.y + i))

for i, pos in enumerate(positions):
    positions[i] = (pos[0] - 2, pos[1] - 4)

return positions

def valid_space(shape, grid):
accepted_positions = [[(j, i) for j in range(10) if grid[i] == (0,0,0)] for i in range(20)]
accepted_positions = [j for sub in accepted_positions for j in sub]
formatted = convert_shape_format(shape)

for pos in formatted:
    if pos not in accepted_positions:
        if pos[1] > -1:
            return False

return True

def check_lost(positions):
for pos in positions:
x, y = pos
if y < 1:
return True
return False

def get_shape():
global shapes, shape_colors

return Piece(5, 0, random.choice(shapes))

def draw_text_middle(text, size, color, surface):
font = pygame.font.SysFont('comicsans', size, bold=True)
label = font.render(text, 1, color)

surface.blit(label, (top_left_x + play_width/2 - (label.get_width() / 2), top_left_y + play_height/2 - label.get_height()/2))

def draw_grid(surface, row, col):
sx = top_left_x
sy = top_left_y
for i in range(row):
pygame.draw.line(surface, (128,128,128), (sx, sy+ i30), (sx + play_width, sy + i 30)) # horizontal lines
for j in range(col):
pygame.draw.line(surface, (128,128,128), (sx + j 30, sy), (sx + j 30, sy + play_height)) # vertical lines

def clear_rows(grid, locked):

# need to see if row is clear the shift every other row above down one

inc = 0
for i in range(len(grid)-1,-1,-1):
    row = grid[i]
    if (0, 0, 0) not in row:
        inc += 1
        # add positions to remove from locked
        ind = i
        for j in range(len(row)):
            try:
                del locked[(j, i)]
            except:
                continue
if inc > 0:
    for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
        x, y = key
        if y < ind:
            newKey = (x, y + inc)
            locked[newKey] = locked.pop(key)

def draw_next_shape(shape, surface):
font = pygame.font.SysFont('comicsans', 30)
label = font.render('Next Shape', 1, (255,255,255))

sx = top_left_x + play_width + 50
sy = top_left_y + play_height/2 - 100
format = shape.shape[shape.rotation % len(shape.shape)]

for i, line in enumerate(format):
    row = list(line)
    for j, column in enumerate(row):
        if column == '0':
            pygame.draw.rect(surface, shape.color, (sx + j*30, sy + i*30, 30, 30), 0)

surface.blit(label, (sx + 10, sy- 30))

def draw_window(surface):
surface.fill((0,0,0))

# Tetris Title
font = pygame.font.SysFont('comicsans', 60)
label = font.render('TETRIS', 1, (255,255,255))

surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), 30))

for i in range(len(grid)):
    for j in range(len(grid[i])):
        pygame.draw.rect(surface, grid[i][j], (top_left_x + j* 30, top_left_y + i * 30, 30, 30), 0)

# draw grid and border
draw_grid(surface, 20, 10)
pygame.draw.rect(surface, (255, 0, 0), (top_left_x, top_left_y, play_width, play_height), 5)
# pygame.display.update()

def main():
global grid

locked_positions = {}  # (x,y):(255,0,0)
grid = create_grid(locked_positions)

change_piece = False
run = True
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0

while run:
    fall_speed = 0.27

    grid = create_grid(locked_positions)
    fall_time += clock.get_rawtime()
    clock.tick()

    # PIECE FALLING CODE
    if fall_time/1000 >= fall_speed:
        fall_time = 0
        current_piece.y += 1
        if not (valid_space(current_piece, grid)) and current_piece.y > 0:
            current_piece.y -= 1
            change_piece = True

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
            pygame.display.quit()
            quit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                current_piece.x -= 1
                if not valid_space(current_piece, grid):
                    current_piece.x += 1

            elif event.key == pygame.K_RIGHT:
                current_piece.x += 1
                if not valid_space(current_piece, grid):
                    current_piece.x -= 1
            elif event.key == pygame.K_UP:
                # rotate shape
                current_piece.rotation = current_piece.rotation + 1 % len(current_piece.shape)
                if not valid_space(current_piece, grid):
                    current_piece.rotation = current_piece.rotation - 1 % len(current_piece.shape)

            if event.key == pygame.K_DOWN:
                # move shape down
                current_piece.y += 1
                if not valid_space(current_piece, grid):
                    current_piece.y -= 1

            '''if event.key == pygame.K_SPACE:
               while valid_space(current_piece, grid):
                   current_piece.y += 1
               current_piece.y -= 1
               print(convert_shape_format(current_piece))\'\'\'  # todo fix

    shape_pos = convert_shape_format(current_piece)

    # add piece to the grid for drawing
    for i in range(len(shape_pos)):
        x, y = shape_pos[i]
        if y > -1:
            grid[y][x] = current_piece.color

    # IF PIECE HIT GROUND
    if change_piece:
        for pos in shape_pos:
            p = (pos[0], pos[1])
            locked_positions[p] = current_piece.color
        current_piece = next_piece
        next_piece = get_shape()
        change_piece = False

        # call four times to check for multiple clear rows
        clear_rows(grid, locked_positions)

    draw_window(win)
    draw_next_shape(next_piece, win)
    pygame.display.update()

    # Check if user lost
    if check_lost(locked_positions):
        run = False

draw_text_middle("You Lost", 40, (255,255,255), win)
pygame.display.update()
pygame.time.delay(2000)

def main_menu():
run = True
while run:
win.fill((0,0,0))
draw_text_middle('Press any key to begin.', 60, (255, 255, 255), win)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

        if event.type == pygame.KEYDOWN:
            main()
pygame.quit()

win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')

main_menu() # Start game