import pygame
import random
import sys

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
TILE_SIZE = 40
PLAYER_SIZE = 30
FPS = 60

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 120, 255)
YELLOW = (255, 255, 0)
WALL_COLOR = (100, 100, 100)
PATH_COLOR = (230, 230, 230)
LIGHT_BLUE = (100, 200, 255)
LIGHT_GREEN = (150, 255, 150)


class MazeGenerator:
    def __init__(self, rows, cols):
        self.rows = rows
        self.cols = cols
        self.maze = [[1 for _ in range(cols)] for _ in range(rows)]

    def generate(self, start_row=1, start_col=1):
        directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
        random.shuffle(directions)

        self.maze[start_row][start_col] = 0

        for dr, dc in directions:
            new_row, new_col = start_row + dr, start_col + dc

            if (0 < new_row < self.rows - 1 and
                0 < new_col < self.cols - 1 and
                    self.maze[new_row][new_col] == 1):

                wall_row, wall_col = start_row + dr//2, start_col + dc//2
                self.maze[wall_row][wall_col] = 0

                self.generate(new_row, new_col)

        return self.maze


class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.rect = pygame.Rect(x, y, PLAYER_SIZE, PLAYER_SIZE)
        self.speed = 5

    def move(self, dx, dy, walls):
        new_x = self.x + dx * self.speed
        new_y = self.y + dy * self.speed

        temp_rect = pygame.Rect(new_x, new_y, PLAYER_SIZE, PLAYER_SIZE)

        collision = False
        for wall in walls:
            if temp_rect.colliderect(wall):
                collision = True
                break

        if not collision:
            self.x = new_x
            self.y = new_y
            self.rect.topleft = (self.x, self.y)

    def draw(self, surface):
        pygame.draw.rect(surface, BLUE, self.rect)
        highlight_rect = pygame.Rect(
            self.x + 5,
            self.y + 5,
            PLAYER_SIZE - 10,
            PLAYER_SIZE - 10
        )
        pygame.draw.rect(surface, LIGHT_BLUE, highlight_rect)


class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("迷宫大冒险")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)
        self.small_font = pygame.font.Font(None, 24)

        self.maze_rows = SCREEN_HEIGHT // TILE_SIZE
        self.maze_cols = SCREEN_WIDTH // TILE_SIZE

        self.generate_maze()

        self.running = True
        self.game_over = False
        self.win = False
        self.start_time = pygame.time.get_ticks()

    def generate_maze(self):
        generator = MazeGenerator(self.maze_rows, self.maze_cols)
        self.maze_grid = generator.generate(1, 1)

        self.maze_grid[1][1] = 0
        self.maze_grid[self.maze_rows-2][self.maze_cols-2] = 0

        self.walls = []
        for row in range(self.maze_rows):
            for col in range(self.maze_cols):
                if self.maze_grid[row][col] == 1:
                    wall_rect = pygame.Rect(
                        col * TILE_SIZE,
                        row * TILE_SIZE,
                        TILE_SIZE,
                        TILE_SIZE
                    )
                    self.walls.append(wall_rect)

        self.player = Player(TILE_SIZE + 5, TILE_SIZE + 5)

        self.exit_rect = pygame.Rect(
            (self.maze_cols-2) * TILE_SIZE + 5,
            (self.maze_rows-2) * TILE_SIZE + 5,
            TILE_SIZE - 10,
            TILE_SIZE - 10
        )

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                elif event.key == pygame.K_r and (self.game_over or self.win):
                    self.generate_maze()
                    self.game_over = False
                    self.win = False
                    self.start_time = pygame.time.get_ticks()

        if not self.game_over and not self.win:
            keys = pygame.key.get_pressed()
            dx, dy = 0, 0

            if keys[pygame.K_LEFT] or keys[pygame.K_a]:
                dx = -1
            if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
                dx = 1
            if keys[pygame.K_UP] or keys[pygame.K_w]:
                dy = -1
            if keys[pygame.K_DOWN] or keys[pygame.K_s]:
                dy = 1

            if dx != 0 or dy != 0:
                self.player.move(dx, dy, self.walls)

                if self.player.rect.colliderect(self.exit_rect):
                    self.win = True

    def draw_maze(self):
        self.screen.fill(BLACK)

        for row in range(self.maze_rows):
            for col in range(self.maze_cols):
                if self.maze_grid[row][col] == 0:
                    rect = pygame.Rect(
                        col * TILE_SIZE,
                        row * TILE_SIZE,
                        TILE_SIZE,
                        TILE_SIZE
                    )
                    pygame.draw.rect(self.screen, PATH_COLOR, rect)

        for wall in self.walls:
            pygame.draw.rect(self.screen, WALL_COLOR, wall)
            pygame.draw.rect(self.screen, (70, 70, 70), wall, 2)

        pygame.draw.rect(self.screen, GREEN, self.exit_rect)

        pulse = (pygame.time.get_ticks() // 200) % 2
        if pulse:
            highlight_rect = pygame.Rect(
                self.exit_rect.x + 2,
                self.exit_rect.y + 2,
                self.exit_rect.width - 4,
                self.exit_rect.height - 4
            )
            pygame.draw.rect(self.screen, LIGHT_GREEN, highlight_rect)

    def draw_ui(self):
        current_time = pygame.time.get_ticks()
        game_time = (current_time - self.start_time) // 1000

        time_text = self.font.render(f"时间: {game_time}秒", True, YELLOW)
        self.screen.blit(time_text, (10, 10))

        controls = [
            "方向键或WASD: 移动",
            "R: 重新开始",
            "ESC: 退出游戏"
        ]

        for i, text in enumerate(controls):
            control_text = self.small_font.render(text, True, WHITE)
            self.screen.blit(control_text, (SCREEN_WIDTH - 200, 10 + i * 25))

        if self.win:
            overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
            overlay.set_alpha(180)
            overlay.fill(BLACK)
            self.screen.blit(overlay, (0, 0))

            win_text = self.font.render("恭喜你！成功走出迷宫！", True, GREEN)
            time_text = self.font.render(f"用时: {game_time}秒", True, YELLOW)
            restart_text = self.small_font.render("按 R 键重新开始", True, WHITE)

            self.screen.blit(win_text, (SCREEN_WIDTH//2 -
                             win_text.get_width()//2, SCREEN_HEIGHT//2 - 50))
            self.screen.blit(time_text, (SCREEN_WIDTH//2 -
                             time_text.get_width()//2, SCREEN_HEIGHT//2))
            self.screen.blit(restart_text, (SCREEN_WIDTH//2 -
                             restart_text.get_width()//2, SCREEN_HEIGHT//2 + 50))

    def draw(self):
        self.draw_maze()
        self.player.draw(self.screen)
        self.draw_ui()

    def run(self):
        while self.running:
            self.handle_events()
            self.draw()
            pygame.display.flip()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    try:
        game = Game()
        game.run()
    except Exception as e:
        print(f"游戏运行出错: {e}")
        import traceback
        traceback.print_exc()
        input("按Enter键退出...")
