import pygame
import sys
import random
import math
import os

pygame.init()

GRID_SIZE = 10
TILE_SIZE = 40
IMAGE_SIZE = GRID_SIZE * TILE_SIZE
SIDEBAR_WIDTH = 220
WIDTH = IMAGE_SIZE + SIDEBAR_WIDTH + 40
HEIGHT = IMAGE_SIZE + 40
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("10x10 交换拼图 - 带参考图")
clock = pygame.time.Clock()
FPS = 60

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (150, 150, 150)
LIGHT_GRAY = (220, 220, 220)
HIGHLIGHT = (255, 200, 0)
CORRECT_COLOR = (0, 200, 0)     # 位置正确块的边框颜色
WRONG_COLOR = (200, 50, 50)     # 位置错误块的边框颜色

font = pygame.font.Font(None, 28)
small_font = pygame.font.Font(None, 22)

def generate_target_image():
    """默认风景图，也可加载本地图片 puzzle_image.png/jpg"""
    for filename in ["puzzle_image.png", "puzzle_image.jpg"]:
        if os.path.exists(filename):
            img = pygame.image.load(filename)
            return pygame.transform.scale(img, (IMAGE_SIZE, IMAGE_SIZE))

    # 生成默认图案（较容易辨认）
    surf = pygame.Surface((IMAGE_SIZE, IMAGE_SIZE))
    # 天空渐变
    for y in range(IMAGE_SIZE):
        t = y / IMAGE_SIZE
        r = int(135 + (255 - 135) * t)
        g = int(206 + (200 - 206) * t)
        b = int(235 + (150 - 235) * t)
        pygame.draw.line(surf, (r, g, b), (0, y), (IMAGE_SIZE, y))
    # 太阳
    pygame.draw.circle(surf, (255, 220, 100), (300, 100), 50)
    # 山脉
    for i in range(0, IMAGE_SIZE, 4):
        h = 180 + 60 * math.sin(i * 0.02)
        pygame.draw.line(surf, (100, 140, 160), (i, int(h)), (i+4, int(h+60*math.cos(i*0.02))), 2)
    # 草地
    pygame.draw.rect(surf, (100, 180, 80), (0, 250, IMAGE_SIZE, IMAGE_SIZE-250))
    # 几个大色块
    pygame.draw.rect(surf, (255, 0, 0), (50, 280, 100, 80))
    pygame.draw.rect(surf, (0, 0, 255), (250, 300, 80, 120))
    pygame.draw.circle(surf, (255, 255, 0), (150, 350), 40)
    return surf

def split_image(image):
    tiles = []
    for row in range(GRID_SIZE):
        for col in range(GRID_SIZE):
            rect = pygame.Rect(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE)
            tile = image.subsurface(rect).copy()
            tiles.append(tile)
    return tiles

def is_solved(positions):
    for i in range(GRID_SIZE * GRID_SIZE):
        if positions[i] != i:
            return False
    return True

def main():
    target_image = generate_target_image()
    tiles = split_image(target_image)

    positions = list(range(GRID_SIZE * GRID_SIZE))
    random.shuffle(positions)
    while is_solved(positions):
        random.shuffle(positions)

    selected = None
    moves = 0
    start_time = pygame.time.get_ticks()

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                x, y = event.pos
                if 10 <= x < 10 + IMAGE_SIZE and 10 <= y < 10 + IMAGE_SIZE:
                    col = (x - 10) // TILE_SIZE
                    row = (y - 10) // TILE_SIZE
                    idx = row * GRID_SIZE + col
                    if selected is None:
                        selected = idx
                    else:
                        if selected != idx:
                            positions[selected], positions[idx] = positions[idx], positions[selected]
                            moves += 1
                        selected = None
                        if is_solved(positions):
                            print(f"拼图完成！用时 {(pygame.time.get_ticks()-start_time)//1000} 秒，步数 {moves}")
                else:
                    selected = None

        screen.fill(GRAY)

        # 绘制拼图块
        for row in range(GRID_SIZE):
            for col in range(GRID_SIZE):
                idx = row * GRID_SIZE + col
                tile_index = positions[idx]
                tile = tiles[tile_index]
                dest_rect = pygame.Rect(10 + col * TILE_SIZE, 10 + row * TILE_SIZE, TILE_SIZE, TILE_SIZE)
                screen.blit(tile, dest_rect)

                # 根据位置是否正确绘制边框
                if tile_index == idx:
                    border_color = CORRECT_COLOR
                else:
                    border_color = WRONG_COLOR
                pygame.draw.rect(screen, border_color, dest_rect, 2)
                # 再叠加网格线
                pygame.draw.rect(screen, BLACK, dest_rect, 1)

        # 高亮选中的块
        if selected is not None:
            row = selected // GRID_SIZE
            col = selected % GRID_SIZE
            highlight_rect = pygame.Rect(10 + col * TILE_SIZE, 10 + row * TILE_SIZE, TILE_SIZE, TILE_SIZE)
            pygame.draw.rect(screen, HIGHLIGHT, highlight_rect, 3)

        # 参考图
        ref_x = IMAGE_SIZE + 30
        ref_y = 30
        pygame.draw.rect(screen, WHITE, (ref_x - 5, ref_y - 5, IMAGE_SIZE//2 + 10, IMAGE_SIZE//2 + 10))
        ref_scaled = pygame.transform.smoothscale(target_image, (IMAGE_SIZE//2, IMAGE_SIZE//2))
        screen.blit(ref_scaled, (ref_x, ref_y))
        pygame.draw.rect(screen, BLACK, (ref_x - 5, ref_y - 5, IMAGE_SIZE//2 + 10, IMAGE_SIZE//2 + 10), 2)

        elapsed = (pygame.time.get_ticks() - start_time) // 1000
        moves_text = font.render(f"步数: {moves}", True, BLACK)
        screen.blit(moves_text, (ref_x, ref_y + IMAGE_SIZE//2 + 20))
        time_text = font.render(f"时间: {elapsed}s", True, BLACK)
        screen.blit(time_text, (ref_x, ref_y + IMAGE_SIZE//2 + 50))
        hint_text = small_font.render("点击两个块交换", True, BLACK)
        screen.blit(hint_text, (ref_x, ref_y + IMAGE_SIZE//2 + 80))

        pygame.display.flip()
        clock.tick(FPS)

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()