import pygame
import random
import sys

# 初始化Pygame
pygame.init()

# 迷宫配置
CELL_SIZE = 40    # 每个格子的大小（像素）
MAZE_WIDTH = 15   # 迷宫宽度（格子数）
MAZE_HEIGHT = 10  # 迷宫高度（格子数）
SCREEN_WIDTH = CELL_SIZE * MAZE_WIDTH
SCREEN_HEIGHT = CELL_SIZE * MAZE_HEIGHT

# 颜色定义（RGB）
BLACK = (0, 0, 0)         # 墙壁颜色
WHITE = (255, 255, 255)   # 路径颜色
RED = (255, 0, 0)         # 玩家颜色
GREEN = (0, 255, 0)       # 终点颜色
BLUE = (0, 0, 255)        # 胜利提示颜色
GRAY = (200, 200, 200)    # 网格辅助色

# 设置窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Python迷宫游戏")
clock = pygame.time.Clock()

class Maze:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # 迷宫网格：每个格子存储四壁状态 [上, 右, 下, 左]，True表示有墙
        self.grid = [[[True, True, True, True] for _ in range(width)] for _ in range(height)]
        self.visited = [[False for _ in range(width)] for _ in range(height)]
        self.generate_maze(0, 0)  # 从左上角开始生成迷宫

    def generate_maze(self, x, y):
        """使用DFS生成迷宫"""
        self.visited[y][x] = True
        # 随机打乱四个方向：上(0), 右(1), 下(2), 左(3)
        directions = [0, 1, 2, 3]
        random.shuffle(directions)

        for dir in directions:
            nx, ny = x, y
            # 根据方向计算相邻格子坐标
            if dir == 0: ny -= 1  # 上
            elif dir == 1: nx += 1  # 右
            elif dir == 2: ny += 1  # 下
            elif dir == 3: nx -= 1  # 左

            # 检查相邻格子是否在范围内且未访问
            if 0 <= nx < self.width and 0 <= ny < self.height and not self.visited[ny][nx]:
                # 移除当前格子和相邻格子之间的墙
                self.grid[y][x][dir] = False
                # 移除相邻格子对应的反方向墙（比如当前格子向右，相邻格子向左）
                self.grid[ny][nx][(dir + 2) % 4] = False
                # 递归访问相邻格子
                self.generate_maze(nx, ny)

    def draw(self):
        """绘制迷宫"""
        screen.fill(WHITE)
        for y in range(self.height):
            for x in range(self.width):
                # 计算格子的像素坐标
                cell_x = x * CELL_SIZE
                cell_y = y * CELL_SIZE
                # 绘制墙壁
                walls = self.grid[y][x]
                if walls[0]:  # 上墙
                    pygame.draw.line(screen, BLACK, (cell_x, cell_y), (cell_x + CELL_SIZE, cell_y), 2)
                if walls[1]:  # 右墙
                    pygame.draw.line(screen, BLACK, (cell_x + CELL_SIZE, cell_y), (cell_x + CELL_SIZE, cell_y + CELL_SIZE), 2)
                if walls[2]:  # 下墙
                    pygame.draw.line(screen, BLACK, (cell_x, cell_y + CELL_SIZE), (cell_x + CELL_SIZE, cell_y + CELL_SIZE), 2)
                if walls[3]:  # 左墙
                    pygame.draw.line(screen, BLACK, (cell_x, cell_y), (cell_x, cell_y + CELL_SIZE), 2)

class Player:
    def __init__(self, maze):
        # 玩家初始位置（左上角）
        self.x = 0
        self.y = 0
        self.maze = maze
        # 玩家角色为圆形，半径为格子大小的一半减边距
        self.radius = CELL_SIZE // 2 - 5

    def move(self, dx, dy):
        """移动玩家，检测碰撞（不能穿墙）"""
        new_x = self.x + dx
        new_y = self.y + dy
        # 检查新位置是否在迷宫范围内
        if 0 <= new_x < maze.width and 0 <= new_y < maze.height:
            # 检测移动方向是否有墙
            if dx == 1:  # 向右
                if not self.maze.grid[self.y][self.x][1]:
                    self.x = new_x
            elif dx == -1:  # 向左
                if not self.maze.grid[self.y][self.x][3]:
                    self.x = new_x
            elif dy == 1:  # 向下
                if not self.maze.grid[self.y][self.x][2]:
                    self.y = new_y
            elif dy == -1:  # 向上
                if not self.maze.grid[self.y][self.x][0]:
                    self.y = new_y

    def draw(self):
        """绘制玩家"""
        # 计算玩家中心像素坐标
        center_x = self.x * CELL_SIZE + CELL_SIZE // 2
        center_y = self.y * CELL_SIZE + CELL_SIZE // 2
        pygame.draw.circle(screen, RED, (center_x, center_y), self.radius)

def draw_end_point():
    """绘制终点（右下角）"""
    center_x = (MAZE_WIDTH - 1) * CELL_SIZE + CELL_SIZE // 2
    center_y = (MAZE_HEIGHT - 1) * CELL_SIZE + CELL_SIZE // 2
    pygame.draw.rect(screen, GREEN, (
        center_x - CELL_SIZE//2 + 5,
        center_y - CELL_SIZE//2 + 5,
        CELL_SIZE - 10,
        CELL_SIZE - 10
    ))

def show_win_message():
    """显示胜利提示"""
    font = pygame.font.Font(None, 60)
    text = font.render("恭喜通关！按R重置", True, BLUE)
    text_rect = text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
    screen.blit(text, text_rect)

# 初始化游戏
maze = Maze(MAZE_WIDTH, MAZE_HEIGHT)
player = Player(maze)
win = False

# 游戏主循环
running = True
while running:
    # 控制帧率（60帧/秒）
    clock.tick(60)

    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 键盘按键（按下时移动）
        if event.type == pygame.KEYDOWN:
            if not win:
                if event.key == pygame.K_UP:
                    player.move(0, -1)
                elif event.key == pygame.K_DOWN:
                    player.move(0, 1)
                elif event.key == pygame.K_LEFT:
                    player.move(-1, 0)
                elif event.key == pygame.K_RIGHT:
                    player.move(1, 0)
            # 重置游戏（按R键）
            if event.key == pygame.K_r:
                maze = Maze(MAZE_WIDTH, MAZE_HEIGHT)
                player = Player(maze)
                win = False

    # 检测是否到达终点（右下角）
    if player.x == MAZE_WIDTH - 1 and player.y == MAZE_HEIGHT - 1:
        win = True

    # 绘制画面
    maze.draw()
    draw_end_point()
    player.draw()
    if win:
        show_win_message()

    # 更新屏幕显示
    pygame.display.flip()

# 退出游戏
pygame.quit()
sys.exit()