import tkinter as tk
from tkinter import messagebox
import random
from enum import Enum

class GameState(Enum):
    PLAYING = "playing"
    WIN = "win"
    LOSE = "lose"

class MinesweeperGUI:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("💣 扫雷 💣")
        self.window.geometry("800x700")
        self.window.configure(bg='#2c3e50')
        self.window.resizable(False, False)
        
        # 游戏设置
        self.rows = 16
        self.cols = 16
        self.mines = 40
        self.cell_size = 35
        self.padding = 10
        
        # 游戏状态
        self.board = []  # 存储每个格子的信息
        self.buttons = []  # 存储按钮引用
        self.first_click = True  # 第一次点击
        self.game_state = GameState.PLAYING
        self.flags = 0
        self.revealed = 0
        self.total_cells = self.rows * self.cols
        
        # 表情符号
        self.emoji = {
            'mine': '💣',
            'flag': '🚩',
            'happy': '😊',
            'sad': '😢',
            'cool': '😎',
            'dead': '💀',
            'win': '🏆'
        }
        
        # 颜色配置
        self.colors = {
            0: '#bdc3c7',
            1: '#3498db',
            2: '#2ecc71',
            3: '#e74c3c',
            4: '#9b59b6',
            5: '#f39c12',
            6: '#1abc9c',
            7: '#2c3e50',
            8: '#7f8c8d'
        }
        
        self.create_widgets()
        self.new_game()
        
    def create_widgets(self):
        """创建界面组件"""
        # 顶部框架
        top_frame = tk.Frame(self.window, bg='#34495e', height=100)
        top_frame.pack(fill=tk.X, padx=10, pady=(10, 5))
        top_frame.pack_propagate(False)
        
        # 标题
        title_label = tk.Label(
            top_frame,
            text="💣 扫 雷 💣",
            font=('微软雅黑', 24, 'bold'),
            bg='#34495e',
            fg='#ecf0f1'
        )
        title_label.pack(pady=5)
        
        # 工具栏
        tool_frame = tk.Frame(top_frame, bg='#34495e')
        tool_frame.pack(fill=tk.X, pady=5)
        
        # 地雷计数
        self.mine_label = tk.Label(
            tool_frame,
            text=f"💣 {self.mines}",
            font=('微软雅黑', 14, 'bold'),
            bg='#34495e',
            fg='#e74c3c'
        )
        self.mine_label.pack(side=tk.LEFT, padx=20)
        
        # 计时器
        self.timer_label = tk.Label(
            tool_frame,
            text="⏱️ 0s",
            font=('微软雅黑', 14, 'bold'),
            bg='#34495e',
            fg='#f1c40f'
        )
        self.timer_label.pack(side=tk.LEFT, padx=20)
        
        # 表情按钮
        self.emoji_button = tk.Button(
            tool_frame,
            text=self.emoji['happy'],
            font=('Arial', 20),
            bg='#34495e',
            fg='#f1c40f',
            relief=tk.FLAT,
            command=self.restart_game
        )
        self.emoji_button.pack(side=tk.LEFT, padx=20)
        
        # 旗子计数
        self.flag_label = tk.Label(
            tool_frame,
            text=f"🚩 0",
            font=('微软雅黑', 14, 'bold'),
            bg='#34495e',
            fg='#f1c40f'
        )
        self.flag_label.pack(side=tk.RIGHT, padx=20)
        
        # 游戏棋盘
        self.board_frame = tk.Frame(self.window, bg='#2c3e50')
        self.board_frame.pack(padx=10, pady=10)
        
        # 底部控制
        bottom_frame = tk.Frame(self.window, bg='#34495e', height=60)
        bottom_frame.pack(fill=tk.X, padx=10, pady=10)
        bottom_frame.pack_propagate(False)
        
        # 难度选择
        difficulties = [
            ("初级 (9x9, 10雷)", 9, 9, 10),
            ("中级 (16x16, 40雷)", 16, 16, 40),
            ("高级 (30x16, 99雷)", 30, 16, 99),
        ]
        
        for text, rows, cols, mines in difficulties:
            tk.Button(
                bottom_frame,
                text=text,
                font=('微软雅黑', 10),
                bg='#3498db',
                fg='white',
                relief=tk.FLAT,
                padx=10,
                pady=5,
                command=lambda r=rows, c=cols, m=mines: self.change_difficulty(r, c, m)
            ).pack(side=tk.LEFT, padx=5)
        
        tk.Button(
            bottom_frame,
            text="🔄 重新开始",
            font=('微软雅黑', 10),
            bg='#e74c3c',
            fg='white',
            relief=tk.FLAT,
            padx=15,
            pady=5,
            command=self.restart_game
        ).pack(side=tk.RIGHT, padx=5)
        
        # 绑定键盘事件
        self.window.bind('<KeyPress>', self.on_key_press)
        
    def new_game(self):
        """新游戏"""
        self.board = [[{'mine': False, 'revealed': False, 'flag': False, 'adjacent': 0} 
                      for _ in range(self.cols)] for _ in range(self.rows)]
        self.buttons = []
        self.first_click = True
        self.game_state = GameState.PLAYING
        self.flags = 0
        self.revealed = 0
        self.timer = 0
        self.timer_running = False
        
        # 创建按钮网格
        for widget in self.board_frame.winfo_children():
            widget.destroy()
            
        for i in range(self.rows):
            row_buttons = []
            for j in range(self.cols):
                btn = tk.Button(
                    self.board_frame,
                    width=2,
                    height=1,
                    font=('Arial', 12, 'bold'),
                    relief=tk.RAISED,
                    bg='#95a5a6',
                    fg='#2c3e50'
                )
                btn.grid(row=i, column=j, padx=1, pady=1, ipadx=5, ipady=5)
                btn.bind('<Button-1>', lambda e, r=i, c=j: self.left_click(r, c))
                btn.bind('<Button-3>', lambda e, r=i, c=j: self.right_click(r, c))
                btn.bind('<Button-2>', lambda e, r=i, c=j: self.middle_click(r, c))
                row_buttons.append(btn)
            self.buttons.append(row_buttons)
        
        self.update_display()
        self.emoji_button.config(text=self.emoji['happy'])
        
    def place_mines(self, safe_row, safe_col):
        """放置地雷（确保第一次点击安全）"""
        # 安全区域
        safe_cells = set()
        for i in range(max(0, safe_row-1), min(self.rows, safe_row+2)):
            for j in range(max(0, safe_col-1), min(self.cols, safe_col+2)):
                safe_cells.add((i, j))
        
        # 放置地雷
        mines_placed = 0
        while mines_placed < self.mines:
            row = random.randint(0, self.rows - 1)
            col = random.randint(0, self.cols - 1)
            if not self.board[row][col]['mine'] and (row, col) not in safe_cells:
                self.board[row][col]['mine'] = True
                mines_placed += 1
        
        # 计算相邻地雷数量
        for i in range(self.rows):
            for j in range(self.cols):
                if not self.board[i][j]['mine']:
                    count = 0
                    for di in [-1, 0, 1]:
                        for dj in [-1, 0, 1]:
                            if di == 0 and dj == 0:
                                continue
                            ni, nj = i + di, j + dj
                            if 0 <= ni < self.rows and 0 <= nj < self.cols:
                                if self.board[ni][nj]['mine']:
                                    count += 1
                    self.board[i][j]['adjacent'] = count
        
        # 开始计时
        self.timer_running = True
        self.update_timer()
        
    def update_timer(self):
        """更新计时器"""
        if self.timer_running and self.game_state == GameState.PLAYING:
            self.timer += 1
            self.timer_label.config(text=f"⏱️ {self.timer}s")
            self.window.after(1000, self.update_timer)
        
    def update_display(self):
        """更新显示"""
        for i in range(self.rows):
            for j in range(self.cols):
                cell = self.board[i][j]
                btn = self.buttons[i][j]
                
                if cell['revealed']:
                    btn.config(relief=tk.SUNKEN, bg='#ecf0f1')
                    if cell['mine']:
                        btn.config(text=self.emoji['mine'], bg='#e74c3c')
                    else:
                        num = cell['adjacent']
                        if num > 0:
                            btn.config(text=str(num), fg=self.colors[num])
                        else:
                            btn.config(text='')
                elif cell['flag']:
                    btn.config(text=self.emoji['flag'], bg='#f1c40f', relief=tk.RAISED)
                else:
                    btn.config(text='', bg='#95a5a6', relief=tk.RAISED)
        
        # 更新计数
        self.mine_label.config(text=f"💣 {self.mines - self.flags}")
        self.flag_label.config(text=f"🚩 {self.flags}")
        
    def left_click(self, row, col):
        """左键点击"""
        if self.game_state != GameState.PLAYING:
            return
        
        cell = self.board[row][col]
        
        if cell['flag']:
            return
            
        if self.first_click:
            self.place_mines(row, col)
            self.first_click = False
            
        self.reveal_cell(row, col)
        self.check_win()
        
    def right_click(self, row, col):
        """右键点击 - 标记/取消旗子"""
        if self.game_state != GameState.PLAYING:
            return
            
        cell = self.board[row][col]
        if cell['revealed']:
            return
            
        cell['flag'] = not cell['flag']
        self.flags += 1 if cell['flag'] else -1
        self.update_display()
        
    def middle_click(self, row, col):
        """中键点击 - 快速展开（如果周围旗子数等于数字）"""
        if self.game_state != GameState.PLAYING:
            return
            
        cell = self.board[row][col]
        if not cell['revealed'] or cell['adjacent'] == 0:
            return
            
        # 计算周围旗子数
        flag_count = 0
        for di in [-1, 0, 1]:
            for dj in [-1, 0, 1]:
                if di == 0 and dj == 0:
                    continue
                ni, nj = row + di, col + dj
                if 0 <= ni < self.rows and 0 <= nj < self.cols:
                    if self.board[ni][nj]['flag']:
                        flag_count += 1
        
        if flag_count == cell['adjacent']:
            for di in [-1, 0, 1]:
                for dj in [-1, 0, 1]:
                    if di == 0 and dj == 0:
                        continue
                    ni, nj = row + di, col + dj
                    if 0 <= ni < self.rows and 0 <= nj < self.cols:
                        if not self.board[ni][nj]['revealed'] and not self.board[ni][nj]['flag']:
                            self.reveal_cell(ni, nj)
            self.check_win()
        
    def reveal_cell(self, row, col):
        """展开单元格"""
        cell = self.board[row][col]
        
        if cell['revealed'] or cell['flag']:
            return
            
        cell['revealed'] = True
        self.revealed += 1
        
        if cell['mine']:
            # 踩雷了
            self.game_lose()
            return
            
        # 如果是空格，展开相邻单元格
        if cell['adjacent'] == 0:
            for di in [-1, 0, 1]:
                for dj in [-1, 0, 1]:
                    if di == 0 and dj == 0:
                        continue
                    ni, nj = row + di, col + dj
                    if 0 <= ni < self.rows and 0 <= nj < self.cols:
                        if not self.board[ni][nj]['revealed']:
                            self.reveal_cell(ni, nj)
        
        self.update_display()
        
    def check_win(self):
        """检查是否获胜"""
        if self.revealed == self.total_cells - self.mines:
            self.game_win()
            
    def game_win(self):
        """游戏胜利"""
        self.game_state = GameState.WIN
        self.timer_running = False
        self.emoji_button.config(text=self.emoji['win'])
        
        # 标记所有地雷
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j]['mine']:
                    self.buttons[i][j].config(text=self.emoji['flag'], bg='#2ecc71')
        
        messagebox.showinfo("🎉 恭喜！", f"你赢了！\n用时: {self.timer}秒")
        
    def game_lose(self):
        """游戏失败"""
        self.game_state = GameState.LOSE
        self.timer_running = False
        self.emoji_button.config(text=self.emoji['dead'])
        
        # 显示所有地雷
        for i in range(self.rows):
            for j in range(self.cols):
                if self.board[i][j]['mine']:
                    self.buttons[i][j].config(text=self.emoji['mine'], bg='#e74c3c')
                elif self.board[i][j]['flag'] and not self.board[i][j]['mine']:
                    self.buttons[i][j].config(text='❌', bg='#f39c12')
        
        messagebox.showinfo("💀 游戏结束", "你踩到了地雷！")
        
    def on_key_press(self, event):
        """键盘事件"""
        if event.char == 'r' or event.char == 'R':
            self.restart_game()
            
    def restart_game(self):
        """重新开始"""
        self.new_game()
        
    def change_difficulty(self, rows, cols, mines):
        """改变难度"""
        self.rows = rows
        self.cols = cols
        self.mines = mines
        self.total_cells = rows * cols
        self.cell_size = min(35, 600 // cols)
        
        # 调整窗口大小
        width = cols * (self.cell_size + 4) + 40
        height = rows * (self.cell_size + 4) + 200
        self.window.geometry(f"{max(800, width)}x{max(700, height)}")
        
        self.new_game()
        
    def run(self):
        """运行游戏"""
        self.window.mainloop()


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