Python

파이썬: 테트리스 소스

코딩ABC 2024. 12. 18. 19:34
반응형
 

파이썬으로 테트리스 게임을 구현하려면 Pygame 라이브러리를 사용하는 것이 일반적입니다. Pygame은 2D 게임을 만들기 위한 다양한 도구를 제공합니다. 아래는 간단한 테트리스 게임의 코드 예제입니다.

 

사전 준비

Pygame을 설치해야 합니다. 아래 명령어를 실행하세요:

pip install pygame

 

pip 실행이 안되면 아래의 링크를 읽어보세요.

https://coding-abc.tistory.com/349

 

 

파이썬: 테트리스 소스

 

 

파이썬: 테트리스 소스 코드

import pygame
import random

# 초기 설정
pygame.init()

# 화면 크기
SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600
GRID_SIZE = 30  # 블록 크기
COLUMNS, ROWS = SCREEN_WIDTH // GRID_SIZE, SCREEN_HEIGHT // GRID_SIZE

# 색상 정의
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
COLORS = [
    (0, 255, 255),  # Cyan
    (0, 0, 255),    # Blue
    (255, 165, 0),  # Orange
    (255, 255, 0),  # Yellow
    (0, 255, 0),    # Green
    (128, 0, 128),  # Purple
    (255, 0, 0),    # Red
]

# 테트리스 블록 모양
SHAPES = [
    [[1, 1, 1, 1]],  # I
    [[1, 1, 1], [0, 1, 0]],  # T
    [[1, 1, 0], [0, 1, 1]],  # Z
    [[0, 1, 1], [1, 1, 0]],  # S
    [[1, 1], [1, 1]],        # O
    [[1, 1, 1], [1, 0, 0]],  # L
    [[1, 1, 1], [0, 0, 1]],  # J
]

class Tetris:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("Tetris")
        self.clock = pygame.time.Clock()
        self.grid = [[0 for _ in range(COLUMNS)] for _ in range(ROWS)]
        self.current_piece = self.new_piece()
        self.next_piece = self.new_piece()
        self.score = 0
        self.running = True

    def new_piece(self):
        """새 블록 생성."""
        shape = random.choice(SHAPES)
        color = random.choice(COLORS)
        return {'shape': shape, 'color': color, 'x': COLUMNS // 2 - len(shape[0]) // 2, 'y': 0}

    def draw_grid(self):
        """그리드를 화면에 그립니다."""
        for y in range(ROWS):
            for x in range(COLUMNS):
                if self.grid[y][x] != 0:
                    pygame.draw.rect(
                        self.screen, self.grid[y][x],
                        (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE)
                    )
        pygame.draw.rect(self.screen, WHITE, (0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 1)

    def draw_piece(self, piece):
        """현재 블록을 그립니다."""
        for i, row in enumerate(piece['shape']):
            for j, value in enumerate(row):
                if value:
                    pygame.draw.rect(
                        self.screen, piece['color'],
                        ((piece['x'] + j) * GRID_SIZE, (piece['y'] + i) * GRID_SIZE, GRID_SIZE, GRID_SIZE)
                    )

    def is_valid(self, piece, dx, dy):
        """블록이 이동 가능한지 확인."""
        for i, row in enumerate(piece['shape']):
            for j, value in enumerate(row):
                if value:
                    nx, ny = piece['x'] + j + dx, piece['y'] + i + dy
                    if nx < 0 or nx >= COLUMNS or ny >= ROWS or (ny >= 0 and self.grid[ny][nx] != 0):
                        return False
        return True

    def lock_piece(self, piece):
        """블록을 고정."""
        for i, row in enumerate(piece['shape']):
            for j, value in enumerate(row):
                if value:
                    self.grid[piece['y'] + i][piece['x'] + j] = piece['color']
        self.clear_lines()

    def clear_lines(self):
        """완성된 줄 제거."""
        new_grid = [row for row in self.grid if any(cell == 0 for cell in row)]
        removed_lines = ROWS - len(new_grid)
        self.grid = [[0 for _ in range(COLUMNS)] for _ in range(removed_lines)] + new_grid
        self.score += removed_lines

    def update(self):
        """게임 로직 업데이트."""
        if not self.is_valid(self.current_piece, 0, 1):
            self.lock_piece(self.current_piece)
            self.current_piece = self.next_piece
            self.next_piece = self.new_piece()
            if not self.is_valid(self.current_piece, 0, 0):
                self.running = False
        else:
            self.current_piece['y'] += 1

    def run(self):
        """게임 실행."""
        drop_time = 500  # 블록이 내려오는 시간(ms)
        last_drop = pygame.time.get_ticks()

        while self.running:
            self.screen.fill(BLACK)
            self.draw_grid()
            self.draw_piece(self.current_piece)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT and self.is_valid(self.current_piece, -1, 0):
                        self.current_piece['x'] -= 1
                    elif event.key == pygame.K_RIGHT and self.is_valid(self.current_piece, 1, 0):
                        self.current_piece['x'] += 1
                    elif event.key == pygame.K_DOWN and self.is_valid(self.current_piece, 0, 1):
                        self.current_piece['y'] += 1
                    elif event.key == pygame.K_UP:
                        rotated_piece = {'shape': [list(row) for row in zip(*self.current_piece['shape'][::-1])],
                                         'color': self.current_piece['color'],
                                         'x': self.current_piece['x'],
                                         'y': self.current_piece['y']}
                        if self.is_valid(rotated_piece, 0, 0):
                            self.current_piece = rotated_piece

            if pygame.time.get_ticks() - last_drop > drop_time:
                self.update()
                last_drop = pygame.time.get_ticks()

            pygame.display.flip()
            self.clock.tick(30)

        print(f"Game Over! Score: {self.score}")
        pygame.quit()

if __name__ == "__main__":
    game = Tetris()
    game.run()

파이썬: 테트리스 소스

반응형