import pygame
import random
pygame.init()
blocks = [
[[1,4,7],[3,4,5]], #straight
[[1,3,4,5,7]], #cross
[[0,1,4,5],[1,3,4,6]], # two on two ones
[[1,2,3,4],[0,3,4,7]],
[[0,1,3,6],[0,1,2,5],[2,5,7,8],[3,6,7,8]],
[[1,2,5,8],[5,6,7,8],[0,3,6,7],[0,1,2,3]],
[[4,6,7,8],[0,3,4,6],[0,1,2,4],[2,4,5,8]]
]
colours = [
(122,78,0),
(0,255,0),
(100,60,200),
(100,50,100),
(50,100,200),
(255,0,0),
(0,0,255)
]
class Block:
def __init__(self,x,y):
self.x = x
self.y = y
self.type = random.randint(0,len(blocks) - 1)
self.rotation = 0
self.colour = colours[random.randint(0,len(colours) -1)]
def shape(self):
return blocks[self.type][self.rotation]
def draw_block(screen, block, grid_size, x_gap, y_gap):
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
pygame.draw.rect(screen,block.colour,
[(x + block.x) * grid_size + x_gap + 1,
(y + block.y) * grid_size + y_gap + 1,grid_size - 2,grid_size - 2])
def collides(block,rows,cols,game_board,ny):
collision = False
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
if y + block.y + ny > rows - 1 or y + block.y + ny < 0:
collision = True
break
if x + block.x > cols - 1 or x + block.x < 0:
collision = True
break
if game_board[x + block.x][y + block.y + ny] != (0,0,0):
collision = True
break
return collision
def rotate(block,rows,cols,game_board):
last_rotate = block.rotation
block.rotation = (block.rotation + 1)%len(blocks[block.type])
can_rotate = True
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
if collides(block,rows,cols,game_board,ny=0):
can_rotate = False
if not can_rotate:
block.rotation = last_rotate
def drawGrid(screen,rows,cols,x_gap,y_gap,grid_size,game_board):
for y in range(rows):
for x in range(cols):
pygame.draw.rect(screen,(100,100,100),[x * grid_size + x_gap,y * grid_size + y_gap,grid_size,grid_size],1)
pygame.draw.rect(screen,game_board[x][y],[x * grid_size + x_gap + 1,y * grid_size + y_gap + 1,grid_size - 2,grid_size - 2])
def dropBlock(block,rows,cols,game_board):
can_drop = True
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
if collides(block,rows,cols,game_board,ny=1):
can_drop = False
if can_drop:
block.y += 1
else:
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
game_board[x + block.x][y + block.y] = block.colour
return can_drop
def sideMove(block,cols,dx):
can_move = True
for y in range(3):
for x in range(3):
if y * 3 + x in block.shape():
if block.x + x >= cols - 1 and dx == 1:
can_move = False
elif block.x + x < 1 and dx == -1:
can_move = False
if can_move:
block.x += dx
def findLines(rows,cols,game_board):
lines = 0
for y in range(rows):
empty = 0
for x in range(cols):
if game_board[x][y] == (0,0,0):
empty += 1
if empty == 0:
lines += 1
for y2 in range(y,1,-1):
for x2 in range(cols):
game_board[x2][y2] = game_board[x2][y2 - 1]
return lines
def main():
screen = pygame.display.set_mode((300,600))
pygame.display.set_caption('Tetris')
grid_size = 30
cols = screen.get_width() // grid_size
rows = screen.get_height() // grid_size
x_gap = (screen.get_width() - cols * grid_size) // 2
y_gap = (screen.get_height() - rows * grid_size) // 2
block = Block((cols - 1) // 2,0)
game_over = False
clock = pygame.time.Clock()
fps = 8
#game board setting black color
game_board = []
for i in range(cols):
new_col = []
for j in range(rows):
new_col.append((0,0,0))
game_board.append(new_col)
score = 0
font = pygame.font.SysFont('Arial', 25, True)
font_quit = pygame.font.SysFont('Arial', 50, True)
finished_text = font_quit.render('Game Over', True, (255,255,255))
text_pos = [(screen.get_width() - finished_text.get_width())// 2, (screen.get_height() - finished_text.get_height()) // 2]
game_finished = False
while not game_over:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
rotate(block,rows,cols,game_board)
if event.type == pygame.KEYDOWN:
if block is not None:
if event.key == pygame.K_LEFT:
sideMove(block,cols,-1)
if event.key == pygame.K_RIGHT:
sideMove(block,cols,1)
screen.fill((0,0,0))
drawGrid(screen,rows,cols,x_gap,y_gap,grid_size,game_board)
if block is not None:
draw_block(screen, block, grid_size, x_gap, y_gap)
if not dropBlock(block,rows,cols,game_board) and not game_finished:
score += findLines(rows,cols,game_board)
block = Block(random.randint(5,cols-5),0)
if collides(block,rows,cols,game_board,ny=0):
game_finished = True
text = font.render("Score: " + str(score), True, (255,255,255))
screen.blit(text, [0,0])
if game_finished == True:
screen.blit(finished_text,text_pos)
pygame.display.update()
pygame.quit()
if __name__ == '__main__':
main()