Advertisement
Guest User

Tetris - Full Code

a guest
Nov 19th, 2018
79,421
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.95 KB | None | 0 0
  1. import pygame
  2. import random
  3.  
  4. """
  5. 10 x 20 square grid
  6. shapes: S, Z, I, O, J, L, T
  7. represented in order by 0 - 6
  8. """
  9.  
  10. pygame.font.init()
  11.  
  12. # GLOBALS VARS
  13. s_width = 800
  14. s_height = 700
  15. play_width = 300  # meaning 300 // 10 = 30 width per block
  16. play_height = 600  # meaning 600 // 20 = 20 height per blo ck
  17. block_size = 30
  18.  
  19. top_left_x = (s_width - play_width) // 2
  20. top_left_y = s_height - play_height
  21.  
  22.  
  23. # SHAPE FORMATS
  24.  
  25. S = [['.....',
  26.       '.....',
  27.       '..00.',
  28.       '.00..',
  29.       '.....'],
  30.      ['.....',
  31.       '..0..',
  32.       '..00.',
  33.       '...0.',
  34.       '.....']]
  35.  
  36. Z = [['.....',
  37.       '.....',
  38.       '.00..',
  39.       '..00.',
  40.       '.....'],
  41.      ['.....',
  42.       '..0..',
  43.       '.00..',
  44.       '.0...',
  45.       '.....']]
  46.  
  47. I = [['..0..',
  48.       '..0..',
  49.       '..0..',
  50.       '..0..',
  51.       '.....'],
  52.      ['.....',
  53.       '0000.',
  54.       '.....',
  55.       '.....',
  56.       '.....']]
  57.  
  58. O = [['.....',
  59.       '.....',
  60.       '.00..',
  61.       '.00..',
  62.       '.....']]
  63.  
  64. J = [['.....',
  65.       '.0...',
  66.       '.000.',
  67.       '.....',
  68.       '.....'],
  69.      ['.....',
  70.       '..00.',
  71.       '..0..',
  72.       '..0..',
  73.       '.....'],
  74.      ['.....',
  75.       '.....',
  76.       '.000.',
  77.       '...0.',
  78.       '.....'],
  79.      ['.....',
  80.       '..0..',
  81.       '..0..',
  82.       '.00..',
  83.       '.....']]
  84.  
  85. L = [['.....',
  86.       '...0.',
  87.       '.000.',
  88.       '.....',
  89.       '.....'],
  90.      ['.....',
  91.       '..0..',
  92.       '..0..',
  93.       '..00.',
  94.       '.....'],
  95.      ['.....',
  96.       '.....',
  97.       '.000.',
  98.       '.0...',
  99.       '.....'],
  100.      ['.....',
  101.       '.00..',
  102.       '..0..',
  103.       '..0..',
  104.       '.....']]
  105.  
  106. T = [['.....',
  107.       '..0..',
  108.       '.000.',
  109.       '.....',
  110.       '.....'],
  111.      ['.....',
  112.       '..0..',
  113.       '..00.',
  114.       '..0..',
  115.       '.....'],
  116.      ['.....',
  117.       '.....',
  118.       '.000.',
  119.       '..0..',
  120.       '.....'],
  121.      ['.....',
  122.       '..0..',
  123.       '.00..',
  124.       '..0..',
  125.       '.....']]
  126.  
  127. shapes = [S, Z, I, O, J, L, T]
  128. shape_colors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)]
  129. # index 0 - 6 represent shape
  130.  
  131.  
  132. class Piece(object):
  133.     rows = 20  # y
  134.     columns = 10  # x
  135.  
  136.     def __init__(self, column, row, shape):
  137.         self.x = column
  138.         self.y = row
  139.         self.shape = shape
  140.         self.color = shape_colors[shapes.index(shape)]
  141.         self.rotation = 0  # number from 0-3
  142.  
  143.  
  144. def create_grid(locked_positions={}):
  145.     grid = [[(0,0,0) for x in range(10)] for x in range(20)]
  146.  
  147.     for i in range(len(grid)):
  148.         for j in range(len(grid[i])):
  149.             if (j,i) in locked_positions:
  150.                 c = locked_positions[(j,i)]
  151.                 grid[i][j] = c
  152.     return grid
  153.  
  154.  
  155. def convert_shape_format(shape):
  156.     positions = []
  157.     format = shape.shape[shape.rotation % len(shape.shape)]
  158.  
  159.     for i, line in enumerate(format):
  160.         row = list(line)
  161.         for j, column in enumerate(row):
  162.             if column == '0':
  163.                 positions.append((shape.x + j, shape.y + i))
  164.  
  165.     for i, pos in enumerate(positions):
  166.         positions[i] = (pos[0] - 2, pos[1] - 4)
  167.  
  168.     return positions
  169.  
  170.  
  171. def valid_space(shape, grid):
  172.     accepted_positions = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)]
  173.     accepted_positions = [j for sub in accepted_positions for j in sub]
  174.     formatted = convert_shape_format(shape)
  175.  
  176.     for pos in formatted:
  177.         if pos not in accepted_positions:
  178.             if pos[1] > -1:
  179.                 return False
  180.  
  181.     return True
  182.  
  183.  
  184. def check_lost(positions):
  185.     for pos in positions:
  186.         x, y = pos
  187.         if y < 1:
  188.             return True
  189.     return False
  190.  
  191.  
  192. def get_shape():
  193.     global shapes, shape_colors
  194.  
  195.     return Piece(5, 0, random.choice(shapes))
  196.  
  197.  
  198. def draw_text_middle(text, size, color, surface):
  199.     font = pygame.font.SysFont('comicsans', size, bold=True)
  200.     label = font.render(text, 1, color)
  201.  
  202.     surface.blit(label, (top_left_x + play_width/2 - (label.get_width() / 2), top_left_y + play_height/2 - label.get_height()/2))
  203.  
  204.  
  205. def draw_grid(surface, row, col):
  206.     sx = top_left_x
  207.     sy = top_left_y
  208.     for i in range(row):
  209.         pygame.draw.line(surface, (128,128,128), (sx, sy+ i*30), (sx + play_width, sy + i * 30))  # horizontal lines
  210.         for j in range(col):
  211.             pygame.draw.line(surface, (128,128,128), (sx + j * 30, sy), (sx + j * 30, sy + play_height))  # vertical lines
  212.  
  213.  
  214. def clear_rows(grid, locked):
  215.     # need to see if row is clear the shift every other row above down one
  216.  
  217.     inc = 0
  218.     for i in range(len(grid)-1,-1,-1):
  219.         row = grid[i]
  220.         if (0, 0, 0) not in row:
  221.             inc += 1
  222.             # add positions to remove from locked
  223.             ind = i
  224.             for j in range(len(row)):
  225.                 try:
  226.                     del locked[(j, i)]
  227.                 except:
  228.                     continue
  229.     if inc > 0:
  230.         for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
  231.             x, y = key
  232.             if y < ind:
  233.                 newKey = (x, y + inc)
  234.                 locked[newKey] = locked.pop(key)
  235.  
  236.  
  237. def draw_next_shape(shape, surface):
  238.     font = pygame.font.SysFont('comicsans', 30)
  239.     label = font.render('Next Shape', 1, (255,255,255))
  240.  
  241.     sx = top_left_x + play_width + 50
  242.     sy = top_left_y + play_height/2 - 100
  243.     format = shape.shape[shape.rotation % len(shape.shape)]
  244.  
  245.     for i, line in enumerate(format):
  246.         row = list(line)
  247.         for j, column in enumerate(row):
  248.             if column == '0':
  249.                 pygame.draw.rect(surface, shape.color, (sx + j*30, sy + i*30, 30, 30), 0)
  250.  
  251.     surface.blit(label, (sx + 10, sy- 30))
  252.  
  253.  
  254. def draw_window(surface):
  255.     surface.fill((0,0,0))
  256.     # Tetris Title
  257.     font = pygame.font.SysFont('comicsans', 60)
  258.     label = font.render('TETRIS', 1, (255,255,255))
  259.  
  260.     surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), 30))
  261.  
  262.     for i in range(len(grid)):
  263.         for j in range(len(grid[i])):
  264.             pygame.draw.rect(surface, grid[i][j], (top_left_x + j* 30, top_left_y + i * 30, 30, 30), 0)
  265.  
  266.     # draw grid and border
  267.     draw_grid(surface, 20, 10)
  268.     pygame.draw.rect(surface, (255, 0, 0), (top_left_x, top_left_y, play_width, play_height), 5)
  269.     # pygame.display.update()
  270.  
  271.  
  272. def main():
  273.     global grid
  274.  
  275.     locked_positions = {}  # (x,y):(255,0,0)
  276.     grid = create_grid(locked_positions)
  277.  
  278.     change_piece = False
  279.     run = True
  280.     current_piece = get_shape()
  281.     next_piece = get_shape()
  282.     clock = pygame.time.Clock()
  283.     fall_time = 0
  284.  
  285.     while run:
  286.         fall_speed = 0.27
  287.  
  288.         grid = create_grid(locked_positions)
  289.         fall_time += clock.get_rawtime()
  290.         clock.tick()
  291.  
  292.         # PIECE FALLING CODE
  293.         if fall_time/1000 >= fall_speed:
  294.             fall_time = 0
  295.             current_piece.y += 1
  296.             if not (valid_space(current_piece, grid)) and current_piece.y > 0:
  297.                 current_piece.y -= 1
  298.                 change_piece = True
  299.  
  300.         for event in pygame.event.get():
  301.             if event.type == pygame.QUIT:
  302.                 run = False
  303.                 pygame.display.quit()
  304.                 quit()
  305.  
  306.             if event.type == pygame.KEYDOWN:
  307.                 if event.key == pygame.K_LEFT:
  308.                     current_piece.x -= 1
  309.                     if not valid_space(current_piece, grid):
  310.                         current_piece.x += 1
  311.  
  312.                 elif event.key == pygame.K_RIGHT:
  313.                     current_piece.x += 1
  314.                     if not valid_space(current_piece, grid):
  315.                         current_piece.x -= 1
  316.                 elif event.key == pygame.K_UP:
  317.                     # rotate shape
  318.                     current_piece.rotation = current_piece.rotation + 1 % len(current_piece.shape)
  319.                     if not valid_space(current_piece, grid):
  320.                         current_piece.rotation = current_piece.rotation - 1 % len(current_piece.shape)
  321.  
  322.                 if event.key == pygame.K_DOWN:
  323.                     # move shape down
  324.                     current_piece.y += 1
  325.                     if not valid_space(current_piece, grid):
  326.                         current_piece.y -= 1
  327.  
  328.                 '''if event.key == pygame.K_SPACE:
  329.                    while valid_space(current_piece, grid):
  330.                        current_piece.y += 1
  331.                    current_piece.y -= 1
  332.                    print(convert_shape_format(current_piece))'''  # todo fix
  333.  
  334.         shape_pos = convert_shape_format(current_piece)
  335.  
  336.         # add piece to the grid for drawing
  337.         for i in range(len(shape_pos)):
  338.             x, y = shape_pos[i]
  339.             if y > -1:
  340.                 grid[y][x] = current_piece.color
  341.  
  342.         # IF PIECE HIT GROUND
  343.         if change_piece:
  344.             for pos in shape_pos:
  345.                 p = (pos[0], pos[1])
  346.                 locked_positions[p] = current_piece.color
  347.             current_piece = next_piece
  348.             next_piece = get_shape()
  349.             change_piece = False
  350.  
  351.             # call four times to check for multiple clear rows
  352.             clear_rows(grid, locked_positions)
  353.  
  354.         draw_window(win)
  355.         draw_next_shape(next_piece, win)
  356.         pygame.display.update()
  357.  
  358.         # Check if user lost
  359.         if check_lost(locked_positions):
  360.             run = False
  361.  
  362.     draw_text_middle("You Lost", 40, (255,255,255), win)
  363.     pygame.display.update()
  364.     pygame.time.delay(2000)
  365.  
  366.  
  367. def main_menu():
  368.     run = True
  369.     while run:
  370.         win.fill((0,0,0))
  371.         draw_text_middle('Press any key to begin.', 60, (255, 255, 255), win)
  372.         pygame.display.update()
  373.         for event in pygame.event.get():
  374.             if event.type == pygame.QUIT:
  375.                 run = False
  376.  
  377.             if event.type == pygame.KEYDOWN:
  378.                 main()
  379.     pygame.quit()
  380.  
  381.  
  382. win = pygame.display.set_mode((s_width, s_height))
  383. pygame.display.set_caption('Tetris')
  384.  
  385. main_menu()  # start game
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement