[파이썬] 숫자 슬라이딩 퍼즐 게임 코드

2026. 1. 27. 14:54IT

반응형

이 퍼즐의 목적은 1부터 8까지의 숫자를 순서대로 맞추고 마지막 칸을 비우는 것입니다.

코드 설명 및 특징

  1. 단계별 검증 및 로직 구성 상태 관리: 퍼즐의 상태는 1부터 8까지의 숫자와 빈 공간(None)을 담은 리스트로 관리됩니다. 이동 규칙: 클릭한 타일이 빈 공간의 인접 구역(상, 하, 좌, 우)일 때만 위치를 바꿉니다. 승리 조건: 리스트의 순서가 [1, 2, 3, 4, 5, 6, 7, 8, None]이 되면 승리 메시지를 띄웁니다.
  2. 기술적 특징  GUI 환경: 텍스트 기반이 아닌 그래픽 인터페이스를 사용하여 실제 게임처럼 즐길 수 있습니다. 반응형 업데이트: 타일을 클릭할 때마다 버튼의 텍스트가 즉시 갱신됩니다.
  3. 실행 방법 파이썬이 설치된 PC에서 위 코드를 복사하여 .py 확장자로 저장합니다. 터미널이나 명령 프롬프트에서 python 파일이름.py를 입력하여 실행합니다.

import tkinter as tk
import random
from tkinter import messagebox

class SlidingPuzzle:
    def __init__(self, root):
        self.root = root
        self.root.title("숫자 슬라이딩 퍼즐")
        self.root.geometry("300x350")
        
        self.board = list(range(1, 9)) + [None]
        self.shuffle_board()
        
        self.buttons = []
        self.create_widgets()

    def shuffle_board(self):
        # 퍼즐이 해결 가능하도록 섞기 위해 무작위 이동을 시뮬레이션합니다.
        for _ in range(100):
            idx = self.board.index(None)
            possible_moves = []
            if idx >= 3: possible_moves.append(idx - 3)  # 상
            if idx < 6: possible_moves.append(idx + 3)   # 하
            if idx % 3 > 0: possible_moves.append(idx - 1) # 좌
            if idx % 3 < 2: possible_moves.append(idx + 1) # 우
            
            move = random.choice(possible_moves)
            self.board[idx], self.board[move] = self.board[move], self.board[idx]

    def create_widgets(self):
        for i in range(9):
            btn_text = str(self.board[i]) if self.board[i] is not None else ""
            btn = tk.Button(self.root, text=btn_text, font=("Arial", 20), width=5, height=2,
                            command=lambda idx=i: self.move_tile(idx))
            btn.grid(row=i // 3, column=i % 3, sticky="nsew")
            self.buttons.append(btn)
            
        reset_btn = tk.Button(self.root, text="다시 시작", command=self.reset_game)
        reset_btn.grid(row=3, column=0, columnspan=3, sticky="nsew")

    def move_tile(self, idx):
        empty_idx = self.board.index(None)
        
        # 선택한 타일이 빈 칸의 상하좌우에 있는지 확인
        if idx in [empty_idx - 1, empty_idx + 1, empty_idx - 3, empty_idx + 3]:
            # 수평 이동 시 행이 바뀌는 경우 방지
            if abs(idx - empty_idx) == 1 and idx // 3 != empty_idx // 3:
                return

            self.board[empty_idx], self.board[idx] = self.board[idx], self.board[empty_idx]
            self.update_buttons()
            
            if self.check_win():
                messagebox.showinfo("승리!", "축하합니다! 퍼즐을 맞췄습니다.")

    def update_buttons(self):
        for i in range(9):
            btn_text = str(self.board[i]) if self.board[i] is not None else ""
            self.buttons[i].config(text=btn_text)

    def check_win(self):
        return self.board == list(range(1, 9)) + [None]

    def reset_game(self):
        self.board = list(range(1, 9)) + [None]
        self.shuffle_board()
        self.update_buttons()

if __name__ == "__main__":
    root = tk.Tk()
    game = SlidingPuzzle(root)
    root.mainloop()

 

반응형