| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- #!/usr/bin/python3
- """
- Competitive tetris server
- """
- import random
- import pygame
- import shapes
- 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 = 30 height per block
- BLOCK_SIZE = 30
- TOP_LEFT_X = (S_WIDTH - PLAY_WIDTH) // 2
- TOP_LEFT_Y = S_HEIGHT - PLAY_HEIGHT
- # SHAPE FORMATS
- # index 0 - 6 represent shape
- class Piece:
- def __init__(self, x, y, shape):
- self.x = x
- self.y = y
- self.shape = shape
- self.color = shapes.SHAPE_COLORS[shapes.SHAPES.index(shape)]
- self.rotation = 0
- def create_grid(locked_pos={}):
- grid = [[(0,0,0) for _ in range(10)] for _ in range(20)]
- for i in range(len(grid)):
- for j in range(len(grid[i])):
- if (j, i) in locked_pos:
- c = locked_pos[(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))
- return positions
- def valid_space(shape, grid):
- accepted_pos = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)]
- accepted_pos = [j for sub in accepted_pos for j in sub]
- formatted = convert_shape_format(shape)
- for pos in formatted:
- if pos not in accepted_pos:
- 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():
- return Piece(0, 0, random.choice(shapes.SHAPES))
- def draw_text_middle(surface, text, size, color):
- 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, grid):
- sx = TOP_LEFT_X
- sy = TOP_LEFT_Y
- for i in range(len(grid)):
- pygame.draw.line(surface, (128,128,128), (sx, sy + i*BLOCK_SIZE), (sx+PLAY_WIDTH, sy+ i*BLOCK_SIZE))
- for j in range(len(grid[i])):
- pygame.draw.line(surface, (128, 128, 128), (sx + j*BLOCK_SIZE, sy),(sx + j*BLOCK_SIZE, sy + PLAY_HEIGHT))
- def clear_rows(grid, locked):
- inc = 0
- for i in range(len(grid)-1, -1, -1):
- row = grid[i]
- if (0,0,0) not in row:
- inc += 1
- 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)
- return inc
- 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 + 0
- 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*BLOCK_SIZE, sy + i*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
- surface.blit(label, (sx + 10, sy - 30))
- def update_score(nscore):
- score = max_score()
- with open('scores.txt', 'w') as f:
- if int(score) > nscore:
- f.write(str(score))
- else:
- f.write(str(nscore))
- def max_score():
- with open('scores.txt', 'r') as f:
- lines = f.readlines()
- score = lines[0].strip()
- return score
- def draw_window(surface, grid, score=0, last_score = 0):
- surface.fill((0, 0, 0))
- pygame.font.init()
- 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))
- # current score
- font = pygame.font.SysFont('comicsans', 30)
- label = font.render('Score: ' + str(score), 1, (255,255,255))
- sx = TOP_LEFT_X + PLAY_WIDTH + 50
- sy = TOP_LEFT_Y + PLAY_HEIGHT/2 - 100
- surface.blit(label, (sx + 20, sy + 160))
- # last score
- label = font.render('High Score: ' + last_score, 1, (255,255,255))
- sx = TOP_LEFT_X - 200
- sy = TOP_LEFT_Y + 200
- surface.blit(label, (sx + 20, sy + 160))
- for i in range(len(grid)):
- for j in range(len(grid[i])):
- pygame.draw.rect(surface, grid[i][j], (TOP_LEFT_X + j*BLOCK_SIZE, TOP_LEFT_Y + i*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
- pygame.draw.rect(surface, (255, 0, 0), (TOP_LEFT_X, TOP_LEFT_Y, PLAY_WIDTH, PLAY_HEIGHT), 5)
- draw_grid(surface, grid)
- #pygame.display.update()
- def main(win): # *
- last_score = max_score()
- locked_positions = {}
- grid = create_grid(locked_positions)
- change_piece = False
- run = True
- current_piece = get_shape()
- current_piece.y = -4
- current_piece.x = 0
- next_piece = get_shape()
- clock = pygame.time.Clock()
- fall_time = 0
- fall_speed = 0.27
- level_time = 0
- score = 0
- while run:
- grid = create_grid(locked_positions)
- fall_time += clock.get_rawtime()
- level_time += clock.get_rawtime()
- clock.tick()
- if level_time/1000 > 5:
- level_time = 0
- if level_time > 0.12:
- level_time -= 0.005
- 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()
- 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
- if event.key == pygame.K_RIGHT:
- current_piece.x += 1
- if not(valid_space(current_piece, grid)):
- current_piece.x -= 1
- if event.key == pygame.K_DOWN:
- current_piece.y += 1
- if not(valid_space(current_piece, grid)):
- current_piece.y -= 1
- if event.key == pygame.K_UP:
- current_piece.rotation += 1
- if not(valid_space(current_piece, grid)):
- current_piece.rotation -= 1
- shape_pos = convert_shape_format(current_piece)
- for i in range(len(shape_pos)):
- x, y = shape_pos[i]
- if y > -1:
- grid[y][x] = current_piece.color
- if change_piece:
- for pos in shape_pos:
- p = (pos[0], pos[1])
- locked_positions[p] = current_piece.color
- current_piece = next_piece
- current_piece.x = 0
- current_piece.y = -4
- next_piece = get_shape()
- change_piece = False
- score += clear_rows(grid, locked_positions) * 10
- draw_window(win, grid, score, last_score)
- draw_next_shape(next_piece, win)
- pygame.display.update()
- if check_lost(locked_positions):
- draw_text_middle(win, "YOU LOST!", 80, (255,255,255))
- pygame.display.update()
- pygame.time.delay(1500)
- run = False
- update_score(score)
- def main_menu(win): # *
- run = True
- while run:
- win.fill((0,0,0))
- draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
- pygame.display.update()
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- run = False
- if event.type == pygame.KEYDOWN:
- main(win)
- pygame.display.quit()
- win = pygame.display.set_mode((S_WIDTH, S_HEIGHT))
- pygame.display.set_caption('Tetris')
- main_menu(win)
|