Python Tkinter 로 2048 게임 만들기

PythonBeginner
지금 연습하기

소개

이 프로젝트에서는 Python 과 Tkinter 라이브러리를 사용하여 간단한 2048 게임을 만드는 방법을 배웁니다. 2048 은 타일을 결합하여 2048 값을 가진 타일에 도달하는 인기 있는 슬라이딩 퍼즐 게임입니다. 이 프로젝트는 가장 현대적이고 아름다운 사용자 인터페이스를 만들지는 않지만, 미적 감각을 향상시키기 위해 구축할 수 있는 견고한 기반을 제공할 것입니다.

👀 미리보기

2048 game

🎯 과제

이 프로젝트에서는 다음을 배우게 됩니다.

  • 게임에 필요한 라이브러리를 가져오는 방법
  • 게임 로직 및 사용자 인터페이스를 처리하기 위한 Game2048 클래스를 만드는 방법
  • Tkinter 를 사용하여 게임 그리드를 그리는 방법
  • 그리드에 초기 타일을 생성하는 방법
  • 게임 그리드의 현재 상태를 반영하도록 사용자 인터페이스를 업데이트하는 방법
  • 타일 값에 따라 타일 색상을 정의하는 방법
  • 타일을 이동하기 위해 키 입력을 처리하는 방법
  • 다양한 방향으로 타일을 이동하는 메서드를 정의하는 방법
  • 게임이 종료되었는지 확인하는 방법

🏆 성과

이 프로젝트를 완료하면 다음을 수행할 수 있습니다.

  • Tkinter 라이브러리를 사용하여 그래픽 사용자 인터페이스를 생성할 수 있습니다.
  • 키 입력을 처리하고 해당 작업을 트리거할 수 있습니다.
  • 게임 상태에 따라 사용자 인터페이스를 업데이트할 수 있습니다.
  • 타일 이동 및 병합에 대한 게임 로직을 구현할 수 있습니다.
  • 게임이 종료되었는지 확인할 수 있습니다.

프로젝트 파일 생성

먼저, 2048_game.py라는 새 파일을 생성하고 선호하는 코드 편집기에서 엽니다.

cd ~/project
touch 2048_game.py

필요한 라이브러리 가져오기

게임을 작동시키려면 필수 라이브러리를 가져와야 합니다. 2048_game.py 파일에 Python 의 random 라이브러리와 그래픽 사용자 인터페이스 (GUI) 를 구축하기 위한 Tkinter 를 포함합니다.

import random
import tkinter as tk

이러한 라이브러리는 게임의 기능과 사용자 인터페이스를 생성하는 데 사용됩니다.

Game2048 클래스 생성

2048_game.py 파일에서 Game2048 클래스를 정의합니다. 이 클래스는 게임의 로직과 사용자 인터페이스를 처리합니다.

class Game2048:
    def __init__(self, root):
        self.root = root
        self.root.title("2048 Game")
        self.root.geometry("400x400")

        ## Initialize the game grid and score
        self.grid = [[0 for _ in range(4)] for _ in range(4)]
        self.score = 0

        ## Create an empty list to store tile labels
        self.tiles = []

여기서는 게임의 루트 윈도우를 초기화하고, 제목과 크기를 설정하며, 게임 그리드를 초기화하고, 게임 타일을 저장할 리스트를 생성하는 클래스 생성자를 만들고 있습니다.

게임 그리드 그리기

Game2048 클래스에 Tkinter 를 사용하여 게임 그리드를 그리는 메서드를 추가합니다. 이 메서드는 초기 사용자 인터페이스 그리드를 생성합니다.

    def draw_grid(self):
        for i in range(4):
            row = []
            for j in range(4):
                cell = tk.Label(self.root, text="", font=("Helvetica", 24), width=5, height=2, borderwidth=4, relief="ridge")
                cell.grid(row=i, column=j, padx=5, pady=5)
                row.append(cell)
            self.tiles.append(row)

이 메서드는 게임 타일을 표시할 4x4 그리드의 레이블을 생성합니다.

초기 타일 생성

이제 게임이 시작될 때 초기 타일을 생성하는 메서드를 구현해야 합니다. 이 메서드는 값 2 또는 4 를 가진 하나 또는 두 개의 타일을 그리드에 배치합니다.

    def spawn_tile(self):
        empty_cells = [(i, j) for i in range(4) for j in range(4) if self.grid[i][j] == 0]
        if empty_cells:
            i, j = random.choice(empty_cells)
            self.grid[i][j] = 2 if random.random() < 0.9 else 4
            self.update_tiles()

이 메서드는 그리드에서 빈 셀을 찾아 무작위로 새 타일을 배치합니다.

사용자 인터페이스 업데이트

현재 게임 그리드의 상태를 반영하도록 사용자 인터페이스를 업데이트하는 메서드를 생성합니다.

    def update_tiles(self):
        for i in range(4):
            for j in range(4):
                tile_value = self.grid[i][j]
                self.tiles[i][j]["text"] = str(tile_value) if tile_value > 0 else ""
                self.tiles[i][j]["background"] = self.get_tile_color(tile_value)

이 메서드는 그리드를 반복하여 그래픽 사용자 인터페이스의 레이블을 그리드의 상태와 일치하도록 업데이트합니다.

타일 색상 정의

타일 값에 따라 배경색을 할당하는 메서드를 생성합니다.

    def get_tile_color(self, value):
        colors = {
            0: "#CDC1B4",
            2: "#EEE4DA",
            4: "#EDE0C8",
            8: "#F2B179",
            16: "#F59563",
            32: "#F67C5F",
            64: "#F65E3B",
            128: "#EDCF72",
            256: "#EDCC61",
            512: "#EDC850",
            1024: "#EDC53F",
            2048: "#EDC22E"
        }
        return colors.get(value, "#FF0000")

이 메서드는 타일의 값을 기반으로 색상 코드를 반환합니다.

키 입력 처리

키 누름을 처리하는 메서드를 구현합니다. 이 단계에서는 화살표 키 누름을 캡처하고 그에 따라 응답합니다.

    def key_pressed(self, event):
        if self.is_game_over():
            return

        if event.keysym == "Up":
            self.move("up")
        elif event.keysym == "Down":
            self.move("down")
        elif event.keysym == "Left":
            self.move("left")
        elif event.keysym == "Right":
            self.move("right")

        self.spawn_tile()
        self.update_tiles()

이 메서드는 화살표 키 누름을 감지하고 해당 이동 함수를 트리거합니다.

타일 이동

원하는 방향 (위, 아래, 왼쪽 또는 오른쪽) 으로 타일을 이동하는 메서드를 구현합니다.

    def move(self, direction):
        if direction == "up":
            self.grid = list(map(list, zip(*self.grid)))
            self.move_left()
            self.grid = list(map(list, zip(*self.grid)))
        elif direction == "down":
            self.grid = list(map(list, zip(*self.grid)))
            self.move_right()
            self.grid = list(map(list, zip(*self.grid)))
        elif direction == "left":
            self.move_left()
        elif direction == "right":
            self.move_right()

이 메서드는 이동을 위해 그리드를 준비하고, 적절한 이동 함수를 호출한 다음 그리드를 재설정합니다.

타일을 왼쪽으로 이동

행 내에서 타일을 왼쪽으로 이동하는 메서드를 정의합니다.

    def move_left(self):
        for i in range(4):
            row = self.grid[i]
            row = [value for value in row if value != 0]
            while len(row) < 4:
                row.append(0)

            for j in range(3):
                if row[j] == row[j + 1] and row[j] != 0:
                    row[j] *= 2
                    row[j + 1] = 0
                    self.score += row[j]

            row = [value for value in row if value != 0]
            while len(row) < 4:
                row.append(0)
            self.grid[i] = row

이 메서드는 타일 이동을 왼쪽으로 처리하고, 가능한 경우 인접한 타일을 병합하며 빈 셀을 채웁니다.

타일을 오른쪽으로 이동

행 내에서 타일을 오른쪽으로 이동하는 메서드를 정의합니다.

    def move_right(self):
        for i in range(4):
            row = self.grid[i]
            row = [value for value in row if value != 0]
            while len(row) < 4:
                row.insert(0, 0)

            for j in range(3, 0, -1):
                if row[j] == row[j - 1] and row[j] != 0:
                    row[j] *= 2
                    row[j - 1] = 0
                    self.score += row[j]

            row = [value for value in row if value != 0]
            while len(row) < 4:
                row.insert(0, 0)
            self.grid[i] = row

이 메서드는 타일을 오른쪽으로 이동시키고, 적절한 경우 병합하며, 빈 공간을 채우는 역할을 합니다.

게임 오버 확인

게임이 종료되었는지 확인하는 메서드를 생성합니다. 게임은 더 이상 이동이 불가능할 때 종료됩니다.

    def is_game_over(self):
        for i in range(4):
            for j in range(4):
                if self.grid[i][j] == 0:
                    return False

        for i in range(4):
            for j in range(3):
                if self.grid[i][j] == self.grid[i][j + 1]:
                    return False

        for j in range(4):
            for i in range(3):
                if self.grid[i][j] == self.grid[i + 1][j]:
                    return False

        return True

이 메서드는 그리드에 빈 셀이나 동일한 값을 가진 인접한 셀이 있는지 검사하여 더 이상 이동이 가능한지 확인합니다. 더 이상 이동이 불가능하면 게임이 종료됩니다.

프로젝트 실행

마지막으로, 데스크톱으로 전환하고 다음 명령을 사용하여 프로젝트를 실행합니다.

python 2048_game.py

2048 game

요약

이 프로젝트에서는 Tkinter 라이브러리를 사용하여 Python 으로 간단한 2048 게임을 만드는 방법을 배웠습니다. 프로젝트를 설정하고, 주요 Python 파일을 생성하고, Game2048 클래스를 정의하는 것으로 시작했습니다. 그런 다음 키 입력을 구현하고, 타일을 이동시키고, 게임 오버 조건을 확인했습니다. 게임 인터페이스가 가장 현대적이고 아름답지는 않지만, 이제 더 세련된 2048 게임을 만들기 위해 향상시키고 사용자 정의할 수 있는 기반을 갖추게 되었습니다. 프로젝트를 실행하려면 아래 단계를 따르세요.

✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습