import pygame
import sys
import random
from collections import deque
import heapq
import time

# 初始化Pygame
pygame.init()
pygame.font.init()

# 游戏窗口设置
SCREEN_WIDTH, SCREEN_HEIGHT = 1000, 700
CELL_SIZE = 30
GRID_COLS = 25
GRID_ROWS = 20
MAZE_WIDTH = GRID_COLS * CELL_SIZE
MAZE_HEIGHT = GRID_ROWS * CELL_SIZE
UI_WIDTH = SCREEN_WIDTH - MAZE_WIDTH

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("迷宫探索者")
clock = pygame.time.Clock()

# 加载字体
try:
    title_font = pygame.font.Font(None, 48)
    header_font = pygame.font.Font(None, 32)
    text_font = pygame.font.Font(None, 24)
    small_font = pygame.font.Font(None, 20)
except:
    title_font = pygame.font.SysFont('arial', 48)
    header_font = pygame.font.SysFont('arial', 32)
    text_font = pygame.font.SysFont('arial', 24)
    small_font = pygame.font.SysFont('arial', 20)

# 颜色主题 (现代深色主题)
COLORS = {
    'bg': (15, 20, 30),
    'maze_bg': (10, 15, 25),
    'wall': (40, 60, 90),
    'wall_light': (60, 85, 120),
    'wall_shadow': (30, 45, 70),
    'path': (25, 30, 40),
    'path_border': (40, 50, 60),
    'start': (50, 180, 100),
    'end': (220, 80, 80),
    'player': (70, 150, 220),
    'player_eye': (240, 240, 240),
    'visited': (40, 100, 150, 100),
    'solution': (180, 100, 220),
    'solution_light': (200, 120, 240),
    'ui_bg': (20, 25, 35, 200),
    'ui_border': (40, 50, 70),
    'text': (220, 220, 220),
    'text_light': (240, 240, 240),
    'highlight': (80, 170, 240),
    'success': (100, 220, 140),
    'button': (40, 60, 90),
    'button_hover': (60, 85, 120),
    'button_text': (240, 240, 240)
}

# 动画效果
class Animation:
    def __init__(self):
        self.win_animation = 0
        self.path_animation = 0
        self.pulse = 0
        self.pulse_dir = 1
    
    def update(self):
        self.win_animation = max(0, self.win_animation - 0.05)
        self.path_animation = (self.path_animation + 0.02) % 1.0
        
        # 脉冲效果
        self.pulse += 0.02 * self.pulse_dir
        if self.pulse >= 1.0:
            self.pulse_dir = -1
        elif self.pulse <= 0.2:
            self.pulse_dir = 1

# 迷宫生成器
class MazeGenerator:
    @staticmethod
    def generate_backtracking(rows, cols):
        """使用递归回溯算法生成迷宫"""
        maze = [[1 for _ in range(cols)] for _ in range(rows)]
        
        # 初始化起点
        start_x, start_y = 1, 1
        maze[start_x][start_y] = 0
        
        stack = [(start_x, start_y)]
        visited = set()
        visited.add((start_x, start_y))
        
        while stack:
            x, y = stack[-1]
            directions = []
            
            # 检查四个方向
            for dx, dy in [(-2, 0), (2, 0), (0, -2), (0, 2)]:
                nx, ny = x + dx, y + dy
                if (1 <= nx < rows-1 and 1 <= ny < cols-1 and 
                    maze[nx][ny] == 1 and (nx, ny) not in visited):
                    directions.append((dx, dy))
            
            if directions:
                dx, dy = random.choice(directions)
                # 打通墙壁
                maze[x + dx//2][y + dy//2] = 0
                maze[x + dx][y + dy] = 0
                stack.append((x + dx, y + dy))
                visited.add((x + dx, y + dy))
            else:
                stack.pop()
        
        # 确保终点是通路
        maze[rows-2][cols-2] = 0
        
        # 添加一些随机开口
        for _ in range(rows * cols // 25):
            x = random.randint(1, rows-2)
            y = random.randint(1, cols-2)
            if maze[x][y] == 1:
                # 检查是否可以打通
                neighbor_walls = 0
                for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                    if 0 <= x+dx < rows and 0 <= y+dy < cols:
                        if maze[x+dx][y+dy] == 1:
                            neighbor_walls += 1
                if neighbor_walls >= 3:
                    maze[x][y] = 0
        
        return maze
    
    @staticmethod
    def generate_prim(rows, cols):
        """使用Prim算法生成迷宫"""
        maze = [[1 for _ in range(cols)] for _ in range(rows)]
        
        # 随机起点
        start_x, start_y = 1, 1
        maze[start_x][start_y] = 0
        
        frontiers = []
        for dx, dy in [(-2, 0), (2, 0), (0, -2), (0, 2)]:
            nx, ny = start_x + dx, start_y + dy
            if 1 <= nx < rows-1 and 1 <= ny < cols-1:
                frontiers.append((nx, ny, start_x, start_y))
        
        while frontiers:
            fx, fy, px, py = random.choice(frontiers)
            frontiers.remove((fx, fy, px, py))
            
            if maze[fx][fy] == 1:
                # 打通墙壁
                maze[fx][fy] = 0
                maze[(fx + px) // 2][(fy + py) // 2] = 0
                
                # 添加新的边界
                for dx, dy in [(-2, 0), (2, 0), (0, -2), (0, 2)]:
                    nx, ny = fx + dx, fy + dy
                    if 1 <= nx < rows-1 and 1 <= ny < cols-1 and maze[nx][ny] == 1:
                        frontiers.append((nx, ny, fx, fy))
        
        # 确保终点是通路
        maze[rows-2][cols-2] = 0
        
        return maze

# 路径查找器
class PathFinder:
    @staticmethod
    def bfs(maze, start, end):
        """广度优先搜索"""
        rows, cols = len(maze), len(maze[0])
        queue = deque([start])
        came_from = {start: None}
        
        while queue:
            current = queue.popleft()
            
            if current == end:
                # 重建路径
                path = []
                while current is not None:
                    path.append(current)
                    current = came_from[current]
                return list(reversed(path))
            
            x, y = current
            for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                nx, ny = x + dx, y + dy
                neighbor = (nx, ny)
                
                if (0 <= nx < rows and 0 <= ny < cols and 
                    maze[nx][ny] == 0 and neighbor not in came_from):
                    queue.append(neighbor)
                    came_from[neighbor] = current
        
        return []
    
    @staticmethod
    def astar(maze, start, end):
        """A*算法"""
        rows, cols = len(maze), len(maze[0])
        
        def heuristic(a, b):
            return abs(a[0] - b[0]) + abs(a[1] - b[1])
        
        open_set = []
        heapq.heappush(open_set, (0, start))
        came_from = {start: None}
        g_score = {start: 0}
        
        while open_set:
            _, current = heapq.heappop(open_set)
            
            if current == end:
                # 重建路径
                path = []
                while current is not None:
                    path.append(current)
                    current = came_from[current]
                return list(reversed(path))
            
            x, y = current
            for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                nx, ny = x + dx, y + dy
                neighbor = (nx, ny)
                
                if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] == 0:
                    tentative_g = g_score[current] + 1
                    
                    if neighbor not in g_score or tentative_g < g_score[neighbor]:
                        came_from[neighbor] = current
                        g_score[neighbor] = tentative_g
                        f_score = tentative_g + heuristic(neighbor, end)
                        heapq.heappush(open_set, (f_score, neighbor))
        
        return []

# 游戏状态
class Game:
    def __init__(self):
        self.rows = GRID_ROWS
        self.cols = GRID_COLS
        self.maze = None
        self.start_pos = (1, 1)
        self.end_pos = (GRID_ROWS-2, GRID_COLS-2)
        self.player_pos = (1, 1)
        self.visited = set([(1, 1)])
        self.solution_path = []
        self.steps = 0
        self.start_time = time.time()
        self.game_won = False
        self.show_solution = False
        self.current_algorithm = None
        self.animation = Animation()
        self.generate_maze('backtracking')
    
    def generate_maze(self, algorithm='backtracking'):
        if algorithm == 'backtracking':
            self.maze = MazeGenerator.generate_backtracking(self.rows, self.cols)
        elif algorithm == 'prim':
            self.maze = MazeGenerator.generate_prim(self.rows, self.cols)
        
        self.start_pos = (1, 1)
        self.end_pos = (self.rows-2, self.cols-2)
        self.player_pos = (1, 1)
        self.visited = set([(1, 1)])
        self.solution_path = []
        self.steps = 0
        self.start_time = time.time()
        self.game_won = False
        self.show_solution = False
        self.current_algorithm = None
        self.animation.win_animation = 0
    
    def move_player(self, dx, dy):
        if self.game_won:
            return False
        
        new_x, new_y = self.player_pos[0] + dx, self.player_pos[1] + dy
        
        if (0 <= new_x < self.rows and 0 <= new_y < self.cols and 
            self.maze[new_x][new_y] == 0):
            self.player_pos = (new_x, new_y)
            self.visited.add(self.player_pos)
            self.steps += 1
            
            if self.player_pos == self.end_pos:
                self.game_won = True
                self.animation.win_animation = 1.0
                return True
            
            return True
        return False
    
    def find_solution(self, algorithm='bfs'):
        self.current_algorithm = algorithm
        
        if algorithm == 'bfs':
            self.solution_path = PathFinder.bfs(self.maze, self.start_pos, self.end_pos)
        elif algorithm == 'astar':
            self.solution_path = PathFinder.astar(self.maze, self.start_pos, self.end_pos)
        
        self.show_solution = True
        return self.solution_path

# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, action=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.action = action
        self.hovered = False
    
    def draw(self, surface):
        color = COLORS['button_hover'] if self.hovered else COLORS['button']
        pygame.draw.rect(surface, color, self.rect, border_radius=5)
        pygame.draw.rect(surface, COLORS['ui_border'], self.rect, 2, border_radius=5)
        
        text_surf = text_font.render(self.text, True, COLORS['button_text'])
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)
    
    def check_hover(self, pos):
        self.hovered = self.rect.collidepoint(pos)
        return self.hovered
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            if self.hovered and self.action:
                return self.action()
        return None

# 游戏主类
class MazeGame:
    def __init__(self):
        self.game = Game()
        self.animation = self.game.animation
        self.buttons = self.create_buttons()
        self.maze_type = 'backtracking'
        self.last_frame_time = time.time()
        
    def create_buttons(self):
        buttons = []
        
        # 按钮位置
        x = MAZE_WIDTH + 20
        button_width = UI_WIDTH - 40
        button_height = 40
        spacing = 10
        
        # 生成迷宫按钮
        buttons.append(Button(x, 120, button_width, button_height, 
                             "生成新迷宫 (R)", lambda: 'generate'))
        
        # 算法选择
        buttons.append(Button(x, 120 + button_height + spacing, 
                             button_width//2 - 5, button_height, 
                             "递归回溯", lambda: ('algorithm', 'backtracking')))
        buttons.append(Button(x + button_width//2 + 5, 120 + button_height + spacing, 
                             button_width//2 - 5, button_height, 
                             "Prim算法", lambda: ('algorithm', 'prim')))
        
        # 路径查找
        y = 120 + 2*(button_height + spacing)
        buttons.append(Button(x, y, button_width, button_height, 
                             "BFS最短路径 (B)", lambda: ('path', 'bfs')))
        
        buttons.append(Button(x, y + button_height + spacing, 
                             button_width, button_height, 
                             "A*算法路径 (A)", lambda: ('path', 'astar')))
        
        buttons.append(Button(x, y + 2*(button_height + spacing), 
                             button_width, button_height, 
                             "隐藏路径 (H)", lambda: 'hide_path'))
        
        return buttons
    
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    return False
                elif event.key == pygame.K_r:
                    self.game.generate_maze(self.maze_type)
                elif event.key == pygame.K_b:
                    self.game.find_solution('bfs')
                elif event.key == pygame.K_a:
                    self.game.find_solution('astar')
                elif event.key == pygame.K_h:
                    self.game.show_solution = False
                elif event.key in [pygame.K_UP, pygame.K_w, pygame.K_KP8]:
                    self.game.move_player(-1, 0)
                elif event.key in [pygame.K_DOWN, pygame.K_s, pygame.K_KP2]:
                    self.game.move_player(1, 0)
                elif event.key in [pygame.K_LEFT, pygame.K_a, pygame.K_KP4]:
                    self.game.move_player(0, -1)
                elif event.key in [pygame.K_RIGHT, pygame.K_d, pygame.K_KP6]:
                    self.game.move_player(0, 1)
            
            elif event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.buttons:
                    result = button.handle_event(event)
                    if result:
                        if result == 'generate':
                            self.game.generate_maze(self.maze_type)
                        elif result[0] == 'algorithm':
                            self.maze_type = result[1]
                            self.game.generate_maze(self.maze_type)
                        elif result[0] == 'path':
                            self.game.find_solution(result[1])
                        elif result == 'hide_path':
                            self.game.show_solution = False
            
            elif event.type == pygame.MOUSEMOTION:
                for button in self.buttons:
                    button.check_hover(event.pos)
        
        return True
    
    def draw_maze(self):
        # 绘制迷宫背景
        pygame.draw.rect(screen, COLORS['maze_bg'], (0, 0, MAZE_WIDTH, MAZE_HEIGHT))
        
        # 绘制迷宫单元格
        for x in range(self.game.rows):
            for y in range(self.game.cols):
                rect = (y * CELL_SIZE, x * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                
                if self.game.maze[x][y] == 1:  # 墙壁
                    # 墙壁3D效果
                    pygame.draw.rect(screen, COLORS['wall'], rect)
                    
                    # 墙壁边缘高光
                    if x > 0 and self.game.maze[x-1][y] == 0:  # 上边缘
                        pygame.draw.line(screen, COLORS['wall_light'], 
                                        (y*CELL_SIZE, x*CELL_SIZE), 
                                        ((y+1)*CELL_SIZE-1, x*CELL_SIZE), 2)
                    
                    if y > 0 and self.game.maze[x][y-1] == 0:  # 左边缘
                        pygame.draw.line(screen, COLORS['wall_light'],
                                        (y*CELL_SIZE, x*CELL_SIZE),
                                        (y*CELL_SIZE, (x+1)*CELL_SIZE-1), 2)
                    
                    # 墙壁阴影
                    if x < self.game.rows-1 and self.game.maze[x+1][y] == 0:  # 下阴影
                        pygame.draw.line(screen, COLORS['wall_shadow'],
                                        (y*CELL_SIZE, (x+1)*CELL_SIZE-1),
                                        ((y+1)*CELL_SIZE-1, (x+1)*CELL_SIZE-1), 2)
                    
                    if y < self.game.cols-1 and self.game.maze[x][y+1] == 0:  # 右阴影
                        pygame.draw.line(screen, COLORS['wall_shadow'],
                                        ((y+1)*CELL_SIZE-1, x*CELL_SIZE),
                                        ((y+1)*CELL_SIZE-1, (x+1)*CELL_SIZE-1), 2)
                
                else:  # 通路
                    pygame.draw.rect(screen, COLORS['path'], rect)
                    pygame.draw.rect(screen, COLORS['path_border'], rect, 1)
        
        # 绘制访问过的路径
        for pos in self.game.visited:
            if pos != self.game.player_pos and pos != self.game.start_pos and pos != self.game.end_pos:
                x, y = pos
                center = (y*CELL_SIZE + CELL_SIZE//2, x*CELL_SIZE + CELL_SIZE//2)
                radius = int(CELL_SIZE * 0.2)
                pygame.draw.circle(screen, COLORS['visited'], center, radius)
        
        # 绘制解决方案路径
        if self.game.show_solution and self.game.solution_path:
            for i, (x, y) in enumerate(self.game.solution_path):
                if (x, y) not in [self.game.start_pos, self.game.end_pos]:
                    # 动画效果
                    alpha = 0.5 + 0.3 * math.sin(self.animation.path_animation * 2*math.pi + i*0.1)
                    color = tuple(int(c * alpha) for c in COLORS['solution'])
                    
                    center = (y*CELL_SIZE + CELL_SIZE//2, x*CELL_SIZE + CELL_SIZE//2)
                    radius = int(CELL_SIZE * 0.25)
                    pygame.draw.circle(screen, color, center, radius)
        
        # 绘制起点
        sx, sy = self.game.start_pos
        start_rect = (sy*CELL_SIZE + 3, sx*CELL_SIZE + 3, CELL_SIZE-6, CELL_SIZE-6)
        pygame.draw.rect(screen, COLORS['start'], start_rect, border_radius=5)
        
        # 绘制终点
        ex, ey = self.game.end_pos
        end_rect = (ey*CELL_SIZE + 3, ex*CELL_SIZE + 3, CELL_SIZE-6, CELL_SIZE-6)
        pygame.draw.rect(screen, COLORS['end'], end_rect, border_radius=5)
        
        # 终点动画效果
        if not self.game.game_won:
            pulse_radius = int(CELL_SIZE * 0.4 * (0.5 + 0.5 * self.animation.pulse))
            end_center = (ey*CELL_SIZE + CELL_SIZE//2, ex*CELL_SIZE + CELL_SIZE//2)
            pygame.draw.circle(screen, COLORS['end'], end_center, pulse_radius, 3)
        
        # 绘制玩家
        px, py = self.game.player_pos
        player_center = (py*CELL_SIZE + CELL_SIZE//2, px*CELL_SIZE + CELL_SIZE//2)
        player_radius = int(CELL_SIZE * 0.35)
        
        # 玩家主体
        pygame.draw.circle(screen, COLORS['player'], player_center, player_radius)
        
        # 玩家眼睛
        eye_radius = player_radius // 4
        eye_offset = player_radius // 3
        
        # 根据移动方向确定眼睛位置
        if len(self.game.visited) > 1:
            visited_list = list(self.game.visited)
            if len(visited_list) >= 2:
                prev_pos = visited_list[-2]
                dx, dy = self.game.player_pos[0] - prev_pos[0], self.game.player_pos[1] - prev_pos[1]
                if dx != 0 or dy != 0:
                    eye_offset_x = eye_offset if dy > 0 else -eye_offset if dy < 0 else 0
                    eye_offset_y = eye_offset if dx > 0 else -eye_offset if dx < 0 else 0
                else:
                    eye_offset_x, eye_offset_y = 0, -eye_offset
            else:
                eye_offset_x, eye_offset_y = 0, -eye_offset
        else:
            eye_offset_x, eye_offset_y = 0, -eye_offset
        
        pygame.draw.circle(screen, COLORS['player_eye'], 
                          (player_center[0] + eye_offset_x, player_center[1] + eye_offset_y), 
                          eye_radius)
        
        # 绘制S和E标记
        start_text = text_font.render("S", True, COLORS['text_light'])
        end_text = text_font.render("E", True, COLORS['text_light'])
        
        screen.blit(start_text, (sy*CELL_SIZE + CELL_SIZE//2 - 5, sx*CELL_SIZE + CELL_SIZE//2 - 8))
        screen.blit(end_text, (ey*CELL_SIZE + CELL_SIZE//2 - 5, ex*CELL_SIZE + CELL_SIZE//2 - 8))
        
        # 胜利动画
        if self.game.game_won and self.animation.win_animation > 0:
            win_radius = int(MAZE_WIDTH * 0.4 * self.animation.win_animation)
            pygame.draw.circle(screen, (255, 255, 255, 100), 
                             (MAZE_WIDTH//2, MAZE_HEIGHT//2), 
                             win_radius, 3)
            
            win_text = title_font.render("成功!", True, COLORS['success'])
            text_rect = win_text.get_rect(center=(MAZE_WIDTH//2, MAZE_HEIGHT//2))
            screen.blit(win_text, text_rect)
    
    def draw_ui(self):
        ui_x = MAZE_WIDTH
        
        # UI背景
        pygame.draw.rect(screen, COLORS['ui_bg'], (ui_x, 0, UI_WIDTH, SCREEN_HEIGHT))
        pygame.draw.line(screen, COLORS['ui_border'], (ui_x, 0), (ui_x, SCREEN_HEIGHT), 3)
        
        # 标题
        title = title_font.render("迷宫探索者", True, COLORS['highlight'])
        screen.blit(title, (ui_x + 20, 20))
        
        # 游戏信息面板
        info_y = 180
        pygame.draw.rect(screen, (30, 35, 45, 200), 
                        (ui_x + 10, info_y, UI_WIDTH - 20, 200), 
                        border_radius=8)
        pygame.draw.rect(screen, COLORS['ui_border'], 
                        (ui_x + 10, info_y, UI_WIDTH - 20, 200), 
                        2, border_radius=8)
        
        info_title = header_font.render("游戏信息", True, COLORS['text_light'])
        screen.blit(info_title, (ui_x + 20, info_y + 15))
        
        # 计算游戏时间
        elapsed_time = time.time() - self.game.start_time
        minutes = int(elapsed_time // 60)
        seconds = int(elapsed_time % 60)
        
        # 统计信息
        info_lines = [
            f"步数: {self.game.steps}",
            f"时间: {minutes:02d}:{seconds:02d}",
            f"已访问: {len(self.game.visited)} 格",
            f"迷宫尺寸: {self.game.rows} × {self.game.cols}",
            f"总格子: {self.game.rows * self.game.cols}",
            f"墙壁比例: {sum(row.count(1) for row in self.game.maze) * 100 // (self.game.rows * self.game.cols)}%"
        ]
        
        for i, line in enumerate(info_lines):
            text = text_font.render(line, True, COLORS['text'])
            screen.blit(text, (ui_x + 20, info_y + 50 + i * 25))
        
        # 算法信息
        algo_y = info_y + 220
        pygame.draw.rect(screen, (30, 35, 45, 200), 
                        (ui_x + 10, algo_y, UI_WIDTH - 20, 200), 
                        border_radius=8)
        pygame.draw.rect(screen, COLORS['ui_border'], 
                        (ui_x + 10, algo_y, UI_WIDTH - 20, 200), 
                        2, border_radius=8)
        
        algo_title = header_font.render("路径算法", True, COLORS['text_light'])
        screen.blit(algo_title, (ui_x + 20, algo_y + 15))
        
        # 计算路径长度
        bfs_path = PathFinder.bfs(self.game.maze, self.game.start_pos, self.game.end_pos)
        astar_path = PathFinder.astar(self.game.maze, self.game.start_pos, self.game.end_pos)
        
        bfs_length = len(bfs_path) - 1 if bfs_path else 0
        astar_length = len(astar_path) - 1 if astar_path else 0
        
        algo_lines = [
            f"当前算法: {self.maze_type}",
            f"BFS路径长度: {bfs_length} 步",
            f"A*路径长度: {astar_length} 步",
            f"你的步数: {self.game.steps} 步"
        ]
        
        for i, line in enumerate(algo_lines):
            text = text_font.render(line, True, COLORS['text'])
            screen.blit(text, (ui_x + 20, algo_y + 50 + i * 25))
        
        # 胜利信息
        if self.game.game_won:
            win_y = algo_y + 180
            pygame.draw.rect(screen, (50, 35, 60, 200), 
                           (ui_x + 10, win_y, UI_WIDTH - 20, 80), 
                           border_radius=8)
            pygame.draw.rect(screen, COLORS['success'], 
                           (ui_x + 10, win_y, UI_WIDTH - 20, 80), 
                           2, border_radius=8)
            
            win_text = text_font.render("恭喜! 到达终点!", True, COLORS['success'])
            screen.blit(win_text, (ui_x + 20, win_y + 20))
            
            efficiency = bfs_length / self.game.steps if self.game.steps > 0 else 0
            eff_text = text_font.render(f"效率: {efficiency:.1%}", True, COLORS['text_light'])
            screen.blit(eff_text, (ui_x + 20, win_y + 50))
        
        # 颜色说明
        colors_y = SCREEN_HEIGHT - 170
        pygame.draw.rect(screen, (30, 35, 45, 200), 
                        (ui_x + 10, colors_y, UI_WIDTH - 20, 150), 
                        border_radius=8)
        pygame.draw.rect(screen, COLORS['ui_border'], 
                        (ui_x + 10, colors_y, UI_WIDTH - 20, 150), 
                        2, border_radius=8)
        
        color_title = text_font.render("颜色说明", True, COLORS['text_light'])
        screen.blit(color_title, (ui_x + 20, colors_y + 10))
        
        # 颜色示例
        color_items = [
            ("起点", COLORS['start']),
            ("终点", COLORS['end']),
            ("玩家", COLORS['player']),
            ("已访问", COLORS['visited']),
            ("最短路径", COLORS['solution'])
        ]
        
        for i, (text, color) in enumerate(color_items):
            pygame.draw.rect(screen, color, (ui_x + 20, colors_y + 40 + i*25, 15, 15))
            text_surf = small_font.render(text, True, COLORS['text'])
            screen.blit(text_surf, (ui_x + 40, colors_y + 40 + i*25))
    
    def draw_buttons(self):
        for button in self.buttons:
            button.draw(screen)
    
    def draw_instructions(self):
        ui_x = MAZE_WIDTH
        y = 60
        
        instructions = [
            "控制说明:",
            "方向键 / WASD: 移动",
            "R: 重新生成迷宫",
            "B: 显示BFS最短路径",
            "A: 显示A*算法路径",
            "H: 隐藏路径显示",
            "ESC: 退出游戏"
        ]
        
        for i, line in enumerate(instructions):
            if i == 0:
                text = header_font.render(line, True, COLORS['highlight'])
            else:
                text = small_font.render(line, True, COLORS['text'])
            screen.blit(text, (ui_x + 20, y + i * 25))
    
    def draw(self):
        # 绘制背景
        screen.fill(COLORS['bg'])
        
        # 绘制迷宫
        self.draw_maze()
        
        # 绘制UI
        self.draw_ui()
        self.draw_instructions()
        self.draw_buttons()
        
        # 更新显示
        pygame.display.flip()
    
    def update(self):
        # 更新动画
        self.animation.update()
        
        # 限制帧率
        current_time = time.time()
        frame_time = current_time - self.last_frame_time
        self.last_frame_time = current_time
        
        return True
    
    def run(self):
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            clock.tick(60)
        
        pygame.quit()
        sys.exit()

# 运行游戏
if __name__ == "__main__":
    game = MazeGame()
    game.run()