import tkinter as tk
from tkinter import messagebox
import random
from copy import deepcopy

class XiaoXiaoLeGUI:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("✨ 消消乐 ✨")
        self.window.geometry("600x700")
        self.window.resizable(False, False)
        
        # 游戏设置
        self.rows = 8
        self.cols = 8
        self.colors = 5
        self.cell_size = 60
        self.padding = 10
        
        # 游戏状态
        self.board = []
        self.score = 0
        self.moves = 0
        self.selected = None  # 选中的格子 (row, col)
        self.buttons = []  # 存储所有按钮引用
        
        # 颜色映射
        self.color_map = {
            1: '#FF6B6B',  # 红色
            2: '#4ECDC4',  # 青色
            3: '#45B7D1',  # 蓝色
            4: '#96CEB4',  # 绿色
            5: '#FFEAA7',  # 黄色
            6: '#DDA0DD',  # 紫色
            7: '#FF8A5C',  # 橙色
            8: '#A8D8EA',  # 淡蓝
        }
        self.symbols = ['●', '■', '▲', '★', '◆', '♥', '♦', '♣']
        
        # 创建界面
        self.create_widgets()
        self.init_game()
        
    def create_widgets(self):
        """创建界面组件"""
        # 标题
        title_frame = tk.Frame(self.window, bg='#2C3E50', height=80)
        title_frame.pack(fill=tk.X, pady=(0, 10))
        title_frame.pack_propagate(False)
        
        title_label = tk.Label(
            title_frame,
            text='✨ 消消乐 ✨',
            font=('微软雅黑', 24, 'bold'),
            bg='#2C3E50',
            fg='white'
        )
        title_label.pack(expand=True)
        
        # 信息栏
        info_frame = tk.Frame(self.window, bg='#ECF0F1', height=50)
        info_frame.pack(fill=tk.X, padx=20, pady=(0, 10))
        info_frame.pack_propagate(False)
        
        self.score_label = tk.Label(
            info_frame,
            text='得分: 0',
            font=('微软雅黑', 14, 'bold'),
            bg='#ECF0F1',
            fg='#2C3E50'
        )
        self.score_label.pack(side=tk.LEFT, padx=20)
        
        self.moves_label = tk.Label(
            info_frame,
            text='步数: 0',
            font=('微软雅黑', 14, 'bold'),
            bg='#ECF0F1',
            fg='#2C3E50'
        )
        self.moves_label.pack(side=tk.RIGHT, padx=20)
        
        # 游戏棋盘 - 使用Canvas绘制
        self.canvas = tk.Canvas(
            self.window,
            width=self.cols * self.cell_size + self.padding * 2,
            height=self.rows * self.cell_size + self.padding * 2,
            bg='#34495E',
            highlightthickness=2,
            highlightbackground='#2C3E50'
        )
        self.canvas.pack(pady=10)
        
        # 底部按钮
        button_frame = tk.Frame(self.window, bg='#ECF0F1', height=60)
        button_frame.pack(fill=tk.X, padx=20, pady=10)
        button_frame.pack_propagate(False)
        
        tk.Button(
            button_frame,
            text='🔄 重新开始',
            font=('微软雅黑', 12),
            bg='#3498DB',
            fg='white',
            relief=tk.FLAT,
            padx=20,
            pady=8,
            command=self.restart_game
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            button_frame,
            text='💡 提示',
            font=('微软雅黑', 12),
            bg='#F39C12',
            fg='white',
            relief=tk.FLAT,
            padx=20,
            pady=8,
            command=self.show_hint
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            button_frame,
            text='🔀 洗牌',
            font=('微软雅黑', 12),
            bg='#9B59B6',
            fg='white',
            relief=tk.FLAT,
            padx=20,
            pady=8,
            command=self.shuffle_board
        ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            button_frame,
            text='📊 统计',
            font=('微软雅黑', 12),
            bg='#E74C3C',
            fg='white',
            relief=tk.FLAT,
            padx=20,
            pady=8,
            command=self.show_stats
        ).pack(side=tk.RIGHT, padx=5)
        
        # 绑定点击事件
        self.canvas.bind('<Button-1>', self.on_click)
        
    def init_game(self):
        """初始化游戏"""
        self.board = [[0] * self.cols for _ in range(self.rows)]
        for i in range(self.rows):
            for j in range(self.cols):
                available = list(range(1, self.colors + 1))
                if j >= 2 and self.board[i][j-1] == self.board[i][j-2]:
                    if self.board[i][j-1] in available:
                        available.remove(self.board[i][j-1])
                if i >= 2 and self.board[i-1][j] == self.board[i-2][j]:
                    if self.board[i-1][j] in available:
                        available.remove(self.board[i-1][j])
                self.board[i][j] = random.choice(available)
        
        self.score = 0
        self.moves = 0
        self.selected = None
        self.update_display()
        
    def draw_board(self):
        """绘制棋盘"""
        self.canvas.delete('all')
        
        for i in range(self.rows):
            for j in range(self.cols):
                x1 = j * self.cell_size + self.padding
                y1 = i * self.cell_size + self.padding
                x2 = x1 + self.cell_size
                y2 = y1 + self.cell_size
                
                value = self.board[i][j]
                color = self.color_map.get(value, '#95A5A6')
                
                # 绘制圆角矩形
                self.canvas.create_rectangle(
                    x1, y1, x2, y2,
                    fill=color,
                    outline='#2C3E50',
                    width=2,
                    tags=f'cell_{i}_{j}'
                )
                
                # 添加高光效果
                self.canvas.create_rectangle(
                    x1+2, y1+2, x2-2, y2-2,
                    fill='',
                    outline='white',
                    width=1,
                    stipple='gray50',
                    tags=f'cell_{i}_{j}'
                )
                
                # 显示符号
                symbol = self.symbols[(value - 1) % len(self.symbols)] if value > 0 else ''
                if value > 0:
                    self.canvas.create_text(
                        (x1 + x2) // 2,
                        (y1 + y2) // 2,
                        text=symbol,
                        font=('Arial', 24, 'bold'),
                        fill='white',
                        tags=f'cell_{i}_{j}'
                    )
                
                # 如果是选中的格子，添加边框高亮
                if self.selected and self.selected == (i, j):
                    self.canvas.create_rectangle(
                        x1-3, y1-3, x2+3, y2+3,
                        outline='#FFD700',
                        width=4,
                        tags=f'cell_{i}_{j}'
                    )
                    
        # 检查游戏是否结束
        if self.is_game_over():
            self.draw_game_over()
            
    def draw_game_over(self):
        """绘制游戏结束覆盖层"""
        self.canvas.create_rectangle(
            0, 0,
            self.cols * self.cell_size + self.padding * 2,
            self.rows * self.cell_size + self.padding * 2,
            fill='black',
            stipple='gray50',
            tags='game_over'
        )
        self.canvas.create_text(
            (self.cols * self.cell_size + self.padding * 2) // 2,
            (self.rows * self.cell_size + self.padding * 2) // 2 - 20,
            text='🎉 游戏结束！',
            font=('微软雅黑', 30, 'bold'),
            fill='white',
            tags='game_over'
        )
        self.canvas.create_text(
            (self.cols * self.cell_size + self.padding * 2) // 2,
            (self.rows * self.cell_size + self.padding * 2) // 2 + 40,
            text=f'最终得分: {self.score}',
            font=('微软雅黑', 20, 'bold'),
            fill='#FFD700',
            tags='game_over'
        )
        
    def update_display(self):
        """更新显示"""
        self.draw_board()
        self.score_label.config(text=f'得分: {self.score}')
        self.moves_label.config(text=f'步数: {self.moves}')
        
    def find_matches(self):
        """查找所有三消的位置"""
        matches = set()
        
        for i in range(self.rows):
            for j in range(self.cols - 2):
                if self.board[i][j] != 0 and self.board[i][j] == self.board[i][j+1] == self.board[i][j+2]:
                    matches.add((i, j))
                    matches.add((i, j+1))
                    matches.add((i, j+2))
        
        for i in range(self.rows - 2):
            for j in range(self.cols):
                if self.board[i][j] != 0 and self.board[i][j] == self.board[i+1][j] == self.board[i+2][j]:
                    matches.add((i, j))
                    matches.add((i+1, j))
                    matches.add((i+2, j))
        
        return matches
    
    def drop_down(self):
        """让元素下落填充空位"""
        dropped = False
        for j in range(self.cols):
            write_pos = self.rows - 1
            for i in range(self.rows - 1, -1, -1):
                if self.board[i][j] != 0:
                    self.board[write_pos][j] = self.board[i][j]
                    if write_pos != i:
                        self.board[i][j] = 0
                        dropped = True
                    write_pos -= 1
            for i in range(write_pos, -1, -1):
                self.board[i][j] = random.randint(1, self.colors)
                dropped = True
        return dropped
    
    def cascade(self):
        """连锁消除"""
        total_eliminated = 0
        while True:
            matches = self.find_matches()
            if not matches:
                break
            
            for (i, j) in matches:
                self.board[i][j] = 0
            
            total_eliminated += len(matches)
            self.score += len(matches) * 10
            self.drop_down()
        
        return total_eliminated > 0
    
    def swap(self, r1, c1, r2, c2):
        """交换两个位置"""
        if not (0 <= r1 < self.rows and 0 <= c1 < self.cols and
                0 <= r2 < self.rows and 0 <= c2 < self.cols):
            return False, "位置超出边界！"
        
        if abs(r1 - r2) + abs(c1 - c2) != 1:
            return False, "两个位置必须相邻！"
        
        if self.board[r1][c1] == self.board[r2][c2]:
            return False, "两个位置元素相同！"
        
        # 执行交换
        self.board[r1][c1], self.board[r2][c2] = self.board[r2][c2], self.board[r1][c1]
        
        # 检查是否有消除
        if not self.find_matches():
            self.board[r1][c1], self.board[r2][c2] = self.board[r2][c2], self.board[r1][c1]
            return False, "无法形成三消！"
        
        self.moves += 1
        self.cascade()
        self.update_display()
        return True, "交换成功！"
    
    def find_hint(self):
        """寻找可用的交换提示"""
        for i in range(self.rows):
            for j in range(self.cols):
                if j < self.cols - 1:
                    self.board[i][j], self.board[i][j+1] = self.board[i][j+1], self.board[i][j]
                    if self.find_matches():
                        self.board[i][j], self.board[i][j+1] = self.board[i][j+1], self.board[i][j]
                        return (i, j, i, j+1)
                    self.board[i][j], self.board[i][j+1] = self.board[i][j+1], self.board[i][j]
                
                if i < self.rows - 1:
                    self.board[i][j], self.board[i+1][j] = self.board[i+1][j], self.board[i][j]
                    if self.find_matches():
                        self.board[i][j], self.board[i+1][j] = self.board[i+1][j], self.board[i][j]
                        return (i, j, i+1, j)
                    self.board[i][j], self.board[i+1][j] = self.board[i+1][j], self.board[i][j]
        return None
    
    def is_game_over(self):
        """检查游戏是否结束"""
        return self.find_hint() is None
    
    def on_click(self, event):
        """处理点击事件"""
        if self.is_game_over():
            return
        
        # 计算点击的格子
        col = (event.x - self.padding) // self.cell_size
        row = (event.y - self.padding) // self.cell_size
        
        if not (0 <= row < self.rows and 0 <= col < self.cols):
            return
        
        if self.selected is None:
            # 第一次选择
            self.selected = (row, col)
            self.draw_board()
            # 高亮选中的格子
            x1 = col * self.cell_size + self.padding
            y1 = row * self.cell_size + self.padding
            x2 = x1 + self.cell_size
            y2 = y1 + self.cell_size
            self.canvas.create_rectangle(
                x1-3, y1-3, x2+3, y2+3,
                outline='#FFD700',
                width=4,
                tags='selected_highlight'
            )
        else:
            # 尝试交换
            r1, c1 = self.selected
            r2, c2 = row, col
            
            # 如果是同一个格子，取消选择
            if r1 == r2 and c1 == c2:
                self.selected = None
                self.draw_board()
                return
            
            # 检查是否相邻
            if abs(r1 - r2) + abs(c1 - c2) == 1:
                success, message = self.swap(r1, c1, r2, c2)
                if not success:
                    # 显示错误信息
                    self.canvas.create_text(
                        self.canvas.winfo_width() // 2,
                        20,
                        text=f'❌ {message}',
                        font=('微软雅黑', 14, 'bold'),
                        fill='red',
                        tags='error_message'
                    )
                    self.window.after(1500, lambda: self.canvas.delete('error_message'))
            else:
                # 选择新的格子
                self.selected = (row, col)
                self.draw_board()
                # 高亮新的选中
                x1 = col * self.cell_size + self.padding
                y1 = row * self.cell_size + self.padding
                x2 = x1 + self.cell_size
                y2 = y1 + self.cell_size
                self.canvas.create_rectangle(
                    x1-3, y1-3, x2+3, y2+3,
                    outline='#FFD700',
                    width=4,
                    tags='selected_highlight'
                )
                return
            
            self.selected = None
            self.update_display()
            
            # 检查游戏是否结束
            if self.is_game_over():
                self.draw_game_over()
    
    def show_hint(self):
        """显示提示"""
        if self.is_game_over():
            messagebox.showinfo('提示', '游戏已经结束，没有可用的移动了！')
            return
        
        hint = self.find_hint()
        if hint:
            r1, c1, r2, c2 = hint
            # 高亮提示的格子
            for (r, c) in [(r1, c1), (r2, c2)]:
                x1 = c * self.cell_size + self.padding
                y1 = r * self.cell_size + self.padding
                x2 = x1 + self.cell_size
                y2 = y1 + self.cell_size
                self.canvas.create_rectangle(
                    x1-3, y1-3, x2+3, y2+3,
                    outline='#00FF00',
                    width=4,
                    tags='hint_highlight'
                )
            self.window.after(3000, lambda: self.canvas.delete('hint_highlight'))
        else:
            messagebox.showinfo('提示', '没有找到可用的移动！')
    
    def shuffle_board(self):
        """重新洗牌"""
        if messagebox.askyesno('确认', '确定要重新洗牌吗？'):
            # 收集所有非零元素
            values = []
            for i in range(self.rows):
                for j in range(self.cols):
                    if self.board[i][j] != 0:
                        values.append(self.board[i][j])
            
            # 随机打乱
            random.shuffle(values)
            
            # 重新填充
            idx = 0
            for i in range(self.rows):
                for j in range(self.cols):
                    self.board[i][j] = values[idx]
                    idx += 1
            
            # 处理可能的三消
            self.cascade()
            self.update_display()
            
            # 检查游戏是否结束
            if self.is_game_over():
                self.draw_game_over()
    
    def restart_game(self):
        """重新开始游戏"""
        if messagebox.askyesno('确认', '确定要重新开始吗？当前进度将丢失！'):
            self.init_game()
            self.selected = None
            self.update_display()
    
    def show_stats(self):
        """显示统计信息"""
        stats = f"""📊 游戏统计
━━━━━━━━━━━━━━━━━━━
得分: {self.score}
步数: {self.moves}
棋盘大小: {self.rows}x{self.cols}
颜色种类: {self.colors}
状态: {"✅ 游戏中" if not self.is_game_over() else "🏁 已结束"}
━━━━━━━━━━━━━━━━━━━"""
        messagebox.showinfo('游戏统计', stats)
    
    def run(self):
        """运行游戏"""
        self.window.mainloop()


if __name__ == '__main__':
    game = XiaoXiaoLeGUI()
    game.run()