import pygame
import sys
import random

# --- 配置常量 ---
CELL_SIZE = 40          # 每个格子的像素大小
COLS, ROWS = 15, 13     # 迷宫列数和行数 (建议奇数，保证有墙)
SCREEN_WIDTH = COLS * CELL_SIZE
SCREEN_HEIGHT = ROWS * CELL_SIZE
FPS = 60

# 颜色定义
COLOR_BG = (20, 20, 20)         # 背景黑
COLOR_WALL = (200, 200, 200)    # 墙壁白
COLOR_PLAYER = (50, 200, 50)    # 玩家绿
COLOR_END = (255, 50, 50)       # 终点红
COLOR_PATH = (50, 50, 100)      # 走过的路径(可选)

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Pygame Random Maze Demo")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)

# --- 迷宫生成类 (DFS算法) ---
class Maze:
    def __init__(self, cols, rows):
        self.cols = cols
        self.rows = rows
        # 初始化全为墙 (True=墙, False=路)
        self.grid = [[True for _ in range(cols)] for _ in range(rows)]
        self.generate()
        
        # 固定起点和终点
        self.start = (1, 1)
        self.end = (cols - 2, rows - 2)
        self.grid[self.start[1]][self.start[0]] = False
        self.grid[self.end[1]][self.end[0]] = False

    def generate(self):
        # DFS 递归回溯法生成迷宫
        stack = [(1, 1)]
        self.grid[1][1] = False
        
        while stack:
            x, y = stack[-1]
            neighbors = []
            
            # 检查上下左右四个方向 (步长为2，保证留下墙壁)
            for dx, dy in [(0, -2), (0, 2), (-2, 0), (2, 0)]:
                nx, ny = x + dx, y + dy
                if 0 < nx < self.cols and 0 < ny < self.rows and self.grid[ny][nx]:
                    neighbors.append((nx, ny, x + dx//2, y + dy//2))
            
            if neighbors:
                nx, ny, wx, wy = random.choice(neighbors)
                self.grid[ny][nx] = False   # 打通目标格子
                self.grid[wy][wx] = False   # 打通中间的墙
                stack.append((nx, ny))
            else:
                stack.pop()

# --- 玩家类 ---
class Player:
    def __init__(self, maze):
        self.maze = maze
        self.reset()

    def reset(self):
        self.col, self.row = self.maze.start
        self.x = self.col * CELL_SIZE
        self.y = self.row * CELL_SIZE
        self.won = False

    def handle_input(self):
        if self.won: return
        
        keys = pygame.key.get_pressed()
        new_col, new_row = self.col, self.row
        
        # 简单的防连按机制 (这里简化处理，实际可加按键事件监听)
        if keys[pygame.K_UP] or keys[pygame.K_w]: new_row -= 1
        elif keys[pygame.K_DOWN] or keys[pygame.K_s]: new_row += 1
        elif keys[pygame.K_LEFT] or keys[pygame.K_a]: new_col -= 1
        elif keys[pygame.K_RIGHT] or keys[pygame.K_d]: new_col += 1
        else: return

        # 边界与墙壁碰撞检测
        if 0 <= new_col < self.maze.cols and 0 <= new_row < self.maze.rows:
            if not self.maze.grid[new_row][new_col]:
                self.col, self.row = new_col, new_row
                self.x = self.col * CELL_SIZE
                self.y = self.row * CELL_SIZE
                
                # 到达终点判定
                if (self.col, self.row) == self.maze.end:
                    self.won = True

    def draw(self, surface):
        rect = pygame.Rect(self.x + 5, self.y + 5, CELL_SIZE - 10, CELL_SIZE - 10)
        pygame.draw.rect(surface, COLOR_PLAYER, rect, border_radius=8)

# --- 主循环 ---
def main():
    maze = Maze(COLS, ROWS)
    player = Player(maze)

    while True:
        clock.tick(FPS)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit(); sys.exit()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
                # 按 R 重新生成迷宫并重置玩家
                maze = Maze(COLS, ROWS)
                player = Player(maze)

        player.handle_input()

        # 绘制
        screen.fill(COLOR_BG)
        
        # 绘制迷宫墙壁
        for r in range(maze.rows):
            for c in range(maze.cols):
                if maze.grid[r][c]:
                    rect = pygame.Rect(c * CELL_SIZE, r * CELL_SIZE, CELL_SIZE, CELL_SIZE)
                    pygame.draw.rect(screen, COLOR_WALL, rect)
                    
        # 绘制终点标记
        end_rect = pygame.Rect(maze.end[0] * CELL_SIZE + 5, maze.end[1] * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10)
        pygame.draw.rect(screen, COLOR_END, end_rect, border_radius=8)
        
        player.draw(screen)

        # UI 提示
        hint_text = font.render("WASD / Arrows to Move | R to Restart", True, (150, 150, 150))
        screen.blit(hint_text, (10, SCREEN_HEIGHT - 30))
        
        if player.won:
            win_text = font.render("YOU WIN! Press R to Play Again", True, COLOR_END)
            text_rect = win_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
            # 画个半透明背景框让字更清晰
            bg_rect = text_rect.inflate(40, 20)
            s = pygame.Surface((bg_rect.width, bg_rect.height), pygame.SRCALPHA)
            s.fill((0, 0, 0, 200))
            screen.blit(s, bg_rect)
            screen.blit(win_text, text_rect)

        pygame.display.flip()

if __name__ == "__main__":
    main()