import random
import tkinter as tk
from tkinter import messagebox, ttk


CELL = 28  # セルのピクセルサイズ


class App083:
    """迷路ゲーム"""

    def __init__(self, root):
        self.root = root
        self.root.title("迷路ゲーム")
        self.root.configure(bg="#f8f9fc")
        self.cols = 21
        self.rows = 15
        self.maze = []  # 1=壁, 0=通路
        self.player = (1, 1)
        self.goal = (self.cols - 2, self.rows - 2)
        self.steps = 0
        self.cleared = False
        self._build_ui()
        self.new_game()

    def _build_ui(self):
        """UI を構築する"""
        title = tk.Frame(self.root, bg="#3776ab", pady=10)
        title.pack(fill=tk.X)
        tk.Label(title, text="迷路ゲーム", font=("Noto Sans JP", 16, "bold"),
                 bg="#3776ab", fg="white").pack()

        ctrl = tk.Frame(self.root, bg="#f8f9fc")
        ctrl.pack(fill=tk.X, pady=6)
        ttk.Label(ctrl, text="サイズ:").pack(side=tk.LEFT, padx=(20, 4))
        self.size_var = tk.StringVar(value="中(21x15)")
        cb = ttk.Combobox(ctrl, textvariable=self.size_var, state="readonly", width=12,
                          values=["小(15x11)", "中(21x15)", "大(27x21)"])
        cb.pack(side=tk.LEFT)
        ttk.Button(ctrl, text="新しい迷路", command=self.new_game).pack(side=tk.LEFT, padx=10)
        self.status = tk.Label(ctrl, text="", bg="#f8f9fc",
                               font=("Noto Sans JP", 11))
        self.status.pack(side=tk.RIGHT, padx=20)

        self.canvas = tk.Canvas(self.root, bg="white", highlightthickness=0)
        self.canvas.pack(padx=10, pady=10)

        # キーバインド (矢印 / WASD)
        for k in ("Up", "Down", "Left", "Right", "w", "a", "s", "d", "W", "A", "S", "D"):
            self.root.bind(f"<{k}>", self._on_key)
        self.root.focus_set()

    def _set_size_from_combo(self):
        """コンボボックスからサイズを決定する"""
        v = self.size_var.get()
        if v.startswith("小"):
            self.cols, self.rows = 15, 11
        elif v.startswith("大"):
            self.cols, self.rows = 27, 21
        else:
            self.cols, self.rows = 21, 15

    def new_game(self):
        """新しい迷路を生成する"""
        self._set_size_from_combo()
        self.maze = self._generate_maze(self.cols, self.rows)
        self.player = (1, 1)
        self.goal = (self.cols - 2, self.rows - 2)
        self.steps = 0
        self.cleared = False
        self.canvas.config(width=self.cols * CELL, height=self.rows * CELL)
        self._draw()
        self.status.config(text="矢印キーで操作 / 歩数: 0", fg="#333")

    def _generate_maze(self, w, h):
        """深さ優先探索で迷路を生成する (奇数サイズ前提)"""
        if w % 2 == 0:
            w += 1
        if h % 2 == 0:
            h += 1
        self.cols, self.rows = w, h
        m = [[1] * w for _ in range(h)]

        def carve(x, y):
            m[y][x] = 0
            dirs = [(2, 0), (-2, 0), (0, 2), (0, -2)]
            random.shuffle(dirs)
            for dx, dy in dirs:
                nx, ny = x + dx, y + dy
                if 0 < nx < w - 1 and 0 < ny < h - 1 and m[ny][nx] == 1:
                    m[y + dy // 2][x + dx // 2] = 0
                    carve(nx, ny)

        carve(1, 1)
        m[h - 2][w - 2] = 0
        return m

    def _draw(self):
        """迷路を描画する"""
        self.canvas.delete("all")
        for y, row in enumerate(self.maze):
            for x, v in enumerate(row):
                x0, y0 = x * CELL, y * CELL
                color = "#1f2933" if v == 1 else "#f8f9fc"
                self.canvas.create_rectangle(x0, y0, x0 + CELL, y0 + CELL,
                                             fill=color, outline="")
        # ゴール
        gx, gy = self.goal
        self.canvas.create_rectangle(gx * CELL + 4, gy * CELL + 4,
                                     (gx + 1) * CELL - 4, (gy + 1) * CELL - 4,
                                     fill="#ffd43b", outline="")
        # プレイヤー
        px, py = self.player
        self.canvas.create_oval(px * CELL + 4, py * CELL + 4,
                                (px + 1) * CELL - 4, (py + 1) * CELL - 4,
                                fill="#3776ab", outline="")

    def _on_key(self, event):
        """キー入力でプレイヤーを移動する"""
        if self.cleared:
            return
        key = event.keysym.lower()
        dx, dy = 0, 0
        if key in ("up", "w"):
            dy = -1
        elif key in ("down", "s"):
            dy = 1
        elif key in ("left", "a"):
            dx = -1
        elif key in ("right", "d"):
            dx = 1
        if dx == 0 and dy == 0:
            return
        x, y = self.player
        nx, ny = x + dx, y + dy
        if 0 <= nx < self.cols and 0 <= ny < self.rows and self.maze[ny][nx] == 0:
            self.player = (nx, ny)
            self.steps += 1
            self._draw()
            self.status.config(text=f"歩数: {self.steps}")
            if self.player == self.goal:
                self.cleared = True
                self.status.config(text=f"クリア！ 歩数: {self.steps}", fg="green")
                self.root.after(200,
                                lambda: messagebox.showinfo(
                                    "クリア！", f"{self.steps} 歩でゴールしました"))


if __name__ == "__main__":
    root = tk.Tk()
    app = App083(root)
    root.mainloop()
