import pygame
import random
import sys

pygame.init()
# 窗口设置
WIDTH = 480
HEIGHT = 560
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("消消乐")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BG_COLOR = (60, 60, 90)
SELECT_COLOR = (255, 220, 60)

# 方块颜色（5种图案）
block_colors = [
    (220, 60, 60),    # 红
    (60, 200, 60),    # 绿
    (60, 120, 220),   # 蓝
    (230, 180, 40),   # 黄
    (180, 80, 200)    # 紫
]

# 字体（海龟编辑器兼容）
font = pygame.font.Font(None, 40)

# 棋盘参数
COL = 8
ROW = 8
CELL_SIZE = 55
offset_x = (WIDTH - COL * CELL_SIZE) // 2
offset_y = 80

# 全局变量
grid = []
selected = None
score = 0
clock = pygame.time.Clock()

# 初始化棋盘
def init_grid():
    global grid
    grid = []
    for y in range(ROW):
        line = []
        for x in range(COL):
            line.append(random.randint(0, len(block_colors)-1))
        grid.append(line)
    # 防止开局就存在可消除组合
    while find_match():
        grid = []
        for y in range(ROW):
            line = []
            for x in range(COL):
                line.append(random.randint(0, len(block_colors)-1))
            grid.append(line)

# 查找可以消除的坐标列表
def find_match():
    match_list = set()
    # 横向检测
    for y in range(ROW):
        x = 0
        while x < COL - 2:
            val = grid[y][x]
            if grid[y][x+1] == val and grid[y][x+2] == val:
                match_list.add((x,y))
                match_list.add((x+1,y))
                match_list.add((x+2,y))
                step = 3
                while x+step < COL and grid[y][x+step]==val:
                    match_list.add((x+step,y))
                    step +=1
                x += step
                continue
            x += 1
    # 纵向检测
    for x in range(COL):
        y = 0
        while y < ROW - 2:
            val = grid[y][x]
            if grid[y+1][x] == val and grid[y+2][x] == val:
                match_list.add((x,y))
                match_list.add((x,y+1))
                match_list.add((x,y+2))
                step = 3
                while y+step < ROW and grid[y+step][x]==val:
                    match_list.add((x,y+step))
                    step +=1
                y += step
                continue
            y += 1
    return list(match_list)

# 交换两个格子
def swap(x1,y1,x2,y2):
    grid[y1][x1], grid[y2][x2] = grid[y2][x2], grid[y1][x1]

# 消除+方块下落+填充新方块
def eliminate():
    global score
    match = find_match()
    if not match:
        return False
    score += len(match) * 10
    # 清空消除方块
    for (x,y) in match:
        grid[y][x] = -1
    # 方块下落
    for x in range(COL):
        empty = 0
        for y in range(ROW-1, -1, -1):
            if grid[y][x] == -1:
                empty +=1
            else:
                if empty>0:
                    grid[y+empty][x] = grid[y][x]
                    grid[y][x] = -1
        # 顶部填充新方块
        for y in range(empty):
            grid[y][x] = random.randint(0, len(block_colors)-1)
    return True

init_grid()
running = True

while running:
    screen.fill(BG_COLOR)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            mx, my = pygame.mouse.get_pos()
            # 换算棋盘坐标
            gx = (mx - offset_x) // CELL_SIZE
            gy = (my - offset_y) // CELL_SIZE
            if 0<=gx<COL and 0<=gy<ROW:
                if selected is None:
                    selected = (gx, gy)
                else:
                    x1,y1 = selected
                    x2,y2 = gx,gy
                    # 判断是否相邻
                    if (abs(x1-x2)==1 and y1==y2) or (abs(y1-y2)==1 and x1==x2):
                        swap(x1,y1,x2,y2)
                        if not find_match():
                            swap(x1,y1,x2,y2) # 交换后无法消除，复原
                    selected = None

    # 持续处理消除连锁
    while eliminate():
        pygame.display.update()
        pygame.time.delay(120)

    # 绘制方块
    for y in range(ROW):
        for x in range(COL):
            val = grid[y][x]
            px = offset_x + x * CELL_SIZE
            py = offset_y + y * CELL_SIZE
            rect = pygame.Rect(px+2, py+2, CELL_SIZE-4, CELL_SIZE-4)
            if val != -1:
                pygame.draw.rect(screen, block_colors[val], rect, border_radius=6)
            # 选中框
            if selected == (x,y):
                pygame.draw.rect(screen, SELECT_COLOR, rect, 3, border_radius=6)

    # 绘制分数
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (20, 20))

    pygame.display.update()
    clock.tick(60)

pygame.quit()
sys.exit()