# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk, messagebox
import random
import time
from collections import deque
import math


class AdvancedMazeGame:
    def __init__(self, root):
        self.root = root
        self.root.title("角色迷宫 - 视野限制版")
        self.root.geometry("1000x800")

        # 角色类型
        self.role_types = {
            "重甲兵": {"speed": 1, "vision": 6, "color": "#4169E1", "name": "重甲兵"},
            "速度兵": {"speed": 2, "vision": 5, "color": "#32CD32", "name": "速度兵"}
        }

        self.current_role = "重甲兵"
        self.maze_size = 50
        self.vision_range = 5
        self.game_over = False

        # 迷宫生成相关
        self.maze = []
        self.player_pos = (1, 1)
        self.exit_pos = (48, 48)

        # UI组件
        self.setup_ui()
        self.generate_maze()

    def setup_ui(self):
        # 控制面板
        control_frame = tk.Frame(self.root, bg="#2c3e50")
        control_frame.pack(fill=tk.X, padx=10, pady=5)

        # 角色选择
        tk.Label(control_frame, text="选择角色:", bg="#2c3e50", fg="white",
                 font=("Microsoft YaHei", 10)).pack(side=tk.LEFT, padx=5)

        self.role_var = tk.StringVar(value="重甲兵")
        role_combo = ttk.Combobox(
            control_frame,
            textvariable=self.role_var,
            values=list(self.role_types.keys()),
            state="readonly",
            width=10,
            font=("Microsoft YaHei", 10)
        )
        role_combo.pack(side=tk.LEFT, padx=5)
        role_combo.bind("<<ComboboxSelected>>", self.change_role)

        # 分隔线
        tk.Label(control_frame, text="|", bg="#2c3e50",
                 fg="white").pack(side=tk.LEFT, padx=10)

        # 游戏控制按钮
        generate_btn = tk.Button(
            control_frame,
            text="生成新迷宫",
            command=self.generate_maze,
            bg="#3498db",
            fg="white",
            font=("Microsoft YaHei", 9)
        )
        generate_btn.pack(side=tk.LEFT, padx=5)

        reset_btn = tk.Button(
            control_frame,
            text="重新开始",
            command=self.reset_game,
            bg="#e74c3c",
            fg="white",
            font=("Microsoft YaHei", 9)
        )
        reset_btn.pack(side=tk.LEFT, padx=5)

        # 状态显示
        stats_frame = tk.Frame(self.root, bg="#34495e")
        stats_frame.pack(fill=tk.X, padx=10, pady=5)

        self.role_label = tk.Label(
            stats_frame,
            text="角色: 重甲兵",
            bg="#34495e",
            fg="#f1c40f",
            font=("Microsoft YaHei", 10, "bold")
        )
        self.role_label.pack(side=tk.LEFT, padx=20)

        self.steps_label = tk.Label(
            stats_frame,
            text="步数: 0",
            bg="#34495e",
            fg="#2ecc71",
            font=("Microsoft YaHei", 10, "bold")
        )
        self.steps_label.pack(side=tk.LEFT, padx=20)

        self.vision_label = tk.Label(
            stats_frame,
            text="视野范围: 5格",
            bg="#34495e",
            fg="#9b59b6",
            font=("Microsoft YaHei", 10, "bold")
        )
        self.vision_label.pack(side=tk.LEFT, padx=20)

        # 迷宫画布
        canvas_frame = tk.Frame(self.root, bg="#2c3e50")
        canvas_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 添加滚动条
        canvas_container = tk.Frame(canvas_frame)
        canvas_container.pack(fill=tk.BOTH, expand=True)

        # 水平和垂直滚动条
        h_scrollbar = tk.Scrollbar(canvas_container, orient=tk.HORIZONTAL)
        h_scrollbar.pack(side=tk.BOTTOM, fill=tk.X)

        v_scrollbar = tk.Scrollbar(canvas_container)
        v_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.canvas = tk.Canvas(
            canvas_container,
            width=800,
            height=600,
            bg="#2c3e50",
            xscrollcommand=h_scrollbar.set,
            yscrollcommand=v_scrollbar.set,
            scrollregion=(0, 0, 2000, 2000)
        )
        self.canvas.pack(fill=tk.BOTH, expand=True)

        h_scrollbar.config(command=self.canvas.xview)
        v_scrollbar.config(command=self.canvas.yview)

        # 操作说明
        help_frame = tk.Frame(self.root, bg="#2c3e50")
        help_frame.pack(fill=tk.X, padx=10, pady=5)

        help_text = """
操作说明: 
方向键(↑↓←→)或WASD控制移动 | 重甲兵:视野6格,移动慢 | 速度兵:视野5格,移动快
红色方块:玩家 | 绿色方块:出口 | 亮色:可见区域 | 暗色:视野外
        """
        help_label = tk.Label(
            help_frame,
            text=help_text,
            bg="#2c3e50",
            fg="#bdc3c7",
            font=("Microsoft YaHei", 9),
            justify=tk.LEFT
        )
        help_label.pack(pady=5)

        # 绑定键盘事件
        self.root.bind("<KeyPress>", self.handle_keypress)
        self.root.focus_set()

        # 初始化步数
        self.steps = 0

    def generate_maze(self):
        """使用深度优先搜索生成迷宫"""
        size = self.maze_size
        self.maze = [[1 for _ in range(size)] for __ in range(size)]

        # 从(1,1)开始
        start_x, start_y = 1, 1
        self.maze[start_x][start_y] = 0

        # 生成路径
        directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
        stack = [(start_x, start_y)]

        while stack:
            x, y = stack[-1]
            random.shuffle(directions)

            moved = False
            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                if 1 <= nx < size-1 and 1 <= ny < size-1 and self.maze[nx][ny] == 1:
                    # 打通墙壁
                    self.maze[x + dx//2][y + dy//2] = 0
                    self.maze[nx][ny] = 0
                    stack.append((nx, ny))
                    moved = True
                    break

            if not moved:
                stack.pop()

        # 确保出口可达
        self.maze[size-2][size-2] = 0
        self.exit_pos = (size-2, size-2)
        self.player_pos = (1, 1)

        # 移除一些死胡同
        for _ in range(size * 2):
            x, y = random.randint(1, size-2), random.randint(1, size-2)
            if self.maze[x][y] == 1:
                # 检查是否可以打通
                wall_count = 0
                for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                    if self.maze[x+dx][y+dy] == 1:
                        wall_count += 1
                if wall_count >= 3:
                    self.maze[x][y] = 0

        self.game_over = False
        self.steps = 0
        self.update_stats()
        self.draw_maze()

    def draw_maze(self):
        """绘制迷宫，只显示视野范围内的部分"""
        self.canvas.delete("all")
        cell_size = 15
        vision = self.role_types[self.current_role]["vision"]

        player_x, player_y = self.player_pos

        # 计算可见范围
        visible_cells = set()
        for dx in range(-vision, vision + 1):
            for dy in range(-vision, vision + 1):
                if abs(dx) + abs(dy) <= vision + 2:  # 菱形视野
                    nx, ny = player_x + dx, player_y + dy
                    if 0 <= nx < self.maze_size and 0 <= ny < self.maze_size:
                        visible_cells.add((nx, ny))

        # 绘制迷宫
        for x in range(self.maze_size):
            for y in range(self.maze_size):
                if (x, y) not in visible_cells:
                    continue

                x1 = y * cell_size
                y1 = x * cell_size
                x2 = x1 + cell_size
                y2 = y1 + cell_size

                if self.maze[x][y] == 1:  # 墙
                    self.canvas.create_rectangle(
                        x1, y1, x2, y2,
                        fill="#4a4a4a",
                        outline="#3a3a3a"
                    )
                else:  # 路
                    self.canvas.create_rectangle(
                        x1, y1, x2, y2,
                        fill="#2c2c2c" if (
                            x, y) in visible_cells else "#1a1a1a",
                        outline="#3a3a3a"
                    )

                # 绘制出口
                if (x, y) == self.exit_pos:
                    self.canvas.create_rectangle(
                        x1+2, y1+2, x2-2, y2-2,
                        fill="#27ae60",
                        outline="#229954"
                    )

        # 绘制玩家
        px, py = self.player_pos
        px1 = py * cell_size + 2
        py1 = px * cell_size + 2
        px2 = px1 + cell_size - 4
        py2 = py1 + cell_size - 4

        role_color = self.role_types[self.current_role]["color"]
        self.canvas.create_oval(
            px1, py1, px2, py2,
            fill=role_color,
            outline="#ffffff",
            width=2
        )

        # 绘制视野范围指示
        for dx in range(-vision, vision + 1):
            for dy in range(-vision, vision + 1):
                if abs(dx) + abs(dy) <= vision:
                    nx, ny = player_x + dx, player_y + dy
                    if 0 <= nx < self.maze_size and 0 <= ny < self.maze_size:
                        vx1 = ny * cell_size
                        vy1 = nx * cell_size
                        vx2 = vx1 + cell_size
                        vy2 = vy1 + cell_size

                        self.canvas.create_rectangle(
                            vx1, vy1, vx2, vy2,
                            outline="#f1c40f",
                            width=1,
                            dash=(2, 2)
                        )

        # 自动滚动到玩家位置
        canvas_x = py * cell_size - 400
        canvas_y = px * cell_size - 300
        self.canvas.xview_moveto(max(0, min(1, canvas_x / 2000)))
        self.canvas.yview_moveto(max(0, min(1, canvas_y / 2000)))

    def change_role(self, event=None):
        """切换角色"""
        self.current_role = self.role_var.get()
        self.vision_range = self.role_types[self.current_role]["vision"]
        self.update_stats()
        self.draw_maze()

    def handle_keypress(self, event):
        """处理键盘输入"""
        if self.game_over:
            return

        dx, dy = 0, 0

        if event.keysym in ["Up", "w", "W"]:
            dx = -1
        elif event.keysym in ["Down", "s", "S"]:
            dx = 1
        elif event.keysym in ["Left", "a", "A"]:
            dy = -1
        elif event.keysym in ["Right", "d", "D"]:
            dy = 1
        else:
            return

        # 根据角色速度决定移动次数
        speed = self.role_types[self.current_role]["speed"]
        for _ in range(speed):
            new_x = self.player_pos[0] + dx
            new_y = self.player_pos[1] + dy

            if 0 <= new_x < self.maze_size and 0 <= new_y < self.maze_size:
                if self.maze[new_x][new_y] == 0:  # 可通行
                    self.player_pos = (new_x, new_y)
                    self.steps += 1
                    self.update_stats()

                    # 检查是否到达出口
                    if self.player_pos == self.exit_pos:
                        self.game_over = True
                        messagebox.showinfo(
                            "通关成功！",
                            f"恭喜{self.current_role}成功走出迷宫！\n"
                            f"总步数: {self.steps}\n"
                            f"地图大小: {self.maze_size}×{self.maze_size}"
                        )

        self.draw_maze()

    def update_stats(self):
        """更新状态显示"""
        self.role_label.config(
            text=f"角色: {self.role_types[self.current_role]['name']}"
        )
        self.steps_label.config(text=f"步数: {self.steps}")
        self.vision_label.config(
            text=f"视野范围: {self.role_types[self.current_role]['vision']}格"
        )

    def reset_game(self):
        """重置游戏"""
        self.player_pos = (1, 1)
        self.game_over = False
        self.steps = 0
        self.update_stats()
        self.draw_maze()


def main():
    root = tk.Tk()
    game = AdvancedMazeGame(root)
    root.mainloop()


if __name__ == "__main__":
    main()
