import pygame
import random
# 초기화
pygame.init()
# 화면 크기
cell_size = 30
cols = 10
rows = 20
width = cell_size * cols
height = cell_size * rows
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Tetris with BGM 🎵')
# 색상
colors = [
(0, 0, 0), # 빈 공간
(255, 0, 0), # 빨강
(0, 255, 0), # 초록
(0, 0, 255), # 파랑
(255, 255, 0), # 노랑
(255, 165, 0), # 주황
(128, 0, 128), # 보라
(0, 255, 255) # 시안
]
# 테트로미노 모양
tetrominoes = [
[[1, 1, 1, 1]], # I
[[2, 2], [2, 2]], # O
[[0, 3, 0], [3, 3, 3]], # T
[[4, 4, 0], [0, 4, 4]], # S
[[0, 5, 5], [5, 5, 0]], # Z
[[6, 0, 0], [6, 6, 6]], # J
[[0, 0, 7], [7, 7, 7]] # L
]
# 배경음악 재생
pygame.mixer.music.load('background.mp3')
pygame.mixer.music.play(-1) # 반복 재생
# 보드 생성
board = [[0 for _ in range(cols)] for _ in range(rows)]
# 블럭 클래스
class Piece:
def __init__(self, tetromino):
self.shape = tetromino
self.x = cols // 2 - len(tetromino[0]) // 2
self.y = 0
def rotate(self):
self.shape = [list(row) for row in zip(*self.shape[::-1])]
def draw_board(board, piece):
screen.fill((0, 0, 0))
for y in range(rows):
for x in range(cols):
color = colors[board[y][x]]
pygame.draw.rect(screen, color, (x * cell_size, y * cell_size, cell_size, cell_size), 0)
pygame.draw.rect(screen, (40, 40, 40), (x * cell_size, y * cell_size, cell_size, cell_size), 1) # 그리드 선
if piece:
for y, row in enumerate(piece.shape):
for x, cell in enumerate(row):
if cell:
pygame.draw.rect(screen, colors[cell],
((piece.x + x) * cell_size, (piece.y + y) * cell_size, cell_size, cell_size), 0)
pygame.draw.rect(screen, (255, 255, 255),
((piece.x + x) * cell_size, (piece.y + y) * cell_size, cell_size, cell_size), 1)
pygame.display.update()
def valid_space(piece, board):
for y, row in enumerate(piece.shape):
for x, cell in enumerate(row):
if cell:
new_x = piece.x + x
new_y = piece.y + y
if new_x < 0 or new_x >= cols or new_y >= rows or (new_y >= 0 and board[new_y][new_x]):
return False
return True
def lock_piece(piece):
global board
for y, row in enumerate(piece.shape):
for x, cell in enumerate(row):
if cell:
board[piece.y + y][piece.x + x] = cell
def clear_lines():
global board
lines_cleared = 0
new_board = [row for row in board if any(cell == 0 for cell in row)]
lines_cleared = rows - len(new_board)
for _ in range(lines_cleared):
new_board.insert(0, [0 for _ in range(cols)])
board = new_board
return lines_cleared
def main():
global board
clock = pygame.time.Clock()
fall_time = 500 # 초기 속도 (밀리초)
fall_counter = 0
piece = Piece(random.choice(tetrominoes))
next_piece = Piece(random.choice(tetrominoes))
running = True
score = 0
while running:
fall_counter += clock.get_rawtime()
clock.tick()
if fall_counter >= fall_time:
piece.y += 1
if not valid_space(piece, board):
piece.y -= 1
lock_piece(piece)
lines = clear_lines()
score += lines * 10
# 속도 증가
if lines > 0:
fall_time = max(100, fall_time - 20)
piece = next_piece
next_piece = Piece(random.choice(tetrominoes))
if not valid_space(piece, board):
running = False
fall_counter = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
piece.x -= 1
if not valid_space(piece, board):
piece.x += 1
elif event.key == pygame.K_RIGHT:
piece.x += 1
if not valid_space(piece, board):
piece.x -= 1
elif event.key == pygame.K_DOWN:
piece.y += 1
if not valid_space(piece, board):
piece.y -= 1
elif event.key == pygame.K_UP:
piece.rotate()
if not valid_space(piece, board):
# 회전 실패 시 복구
for _ in range(3):
piece.rotate()
draw_board(board, piece)
pygame.quit()
print(f'Game Over! Your score: {score}')
if __name__ == '__main__':
main()