import tkinter as tk
from tkinter import messagebox
import random

class TicTacToeAI:
    def __init__(self, root):
        self.root = root
        self.root.title("045. 井字棋 AI 对战")
        self.root.resizable(False, False)

        self.board = [0] * 9  # 0=空, 1=玩家, -1=AI
        self.player = 1
        self.ai = -1
        self.game_over = False
        self.wins = 0
        self.losses = 0
        self.draws = 0

        self.build_ui()
        self.update_status()

    def build_ui(self):
        tk.Label(
            self.root, text="❌⭕ 井字棋 AI 对战",
            font=("微软雅黑", 18, "bold")
        ).pack(pady=10)

        # 棋盘
        board_frame = tk.Frame(self.root)
        board_frame.pack(pady=5)

        self.buttons = []
        for i in range(9):
            btn = tk.Button(
                board_frame, text="",
                width=6, height=3,
                font=("Arial", 20, "bold"),
                command=lambda idx=i: self.player_move(idx)
            )
            btn.grid(row=i // 3, column=i % 3, padx=2, pady=2)
            self.buttons.append(btn)

        # 状态栏
        self.status_label = tk.Label(
            self.root, text="", font=("微软雅黑", 12)
        )
        self.status_label.pack(pady=8)

        # 统计
        self.stat_label = tk.Label(
            self.root, text="胜：0  负：0  平：0",
            font=("Consolas", 10)
        )
        self.stat_label.pack()

        # 按钮
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=10)

        tk.Button(
            btn_frame, text="🔄 再来一局",
            width=14, height=2,
            bg="#4CAF50", fg="white",
            font=("微软雅黑", 11, "bold"),
            command=self.reset_game
        ).pack(side=tk.LEFT, padx=8)

        tk.Button(
            btn_frame, text="退出",
            width=10, height=2,
            bg="#f44336", fg="white",
            font=("微软雅黑", 10),
            command=self.root.quit
        ).pack(side=tk.LEFT, padx=8)

    def player_move(self, idx):
        if self.game_over or self.board[idx] != 0:
            return

        self.board[idx] = self.player
        self.buttons[idx].config(text="❌", fg="#E53935", state="disabled")

        if self.check_win(self.player):
            self.end_game("🎉 你赢了！")
            self.wins += 1
            return

        if self.is_full():
            self.end_game("🤝 平局！")
            self.draws += 1
            return

        self.status_label.config(text="AI 思考中...")
        self.root.update()

        # AI 走棋
        self.root.after(300, self.ai_move)

    def ai_move(self):
        best_move = self.get_best_move()
        if best_move is not None:
            self.board[best_move] = self.ai
            self.buttons[best_move].config(text="⭕", fg="#1565C0", state="disabled")

        if self.check_win(self.ai):
            self.end_game("😎 AI 赢了！")
            self.losses += 1
            return

        if self.is_full():
            self.end_game("🤝 平局！")
            self.draws += 1
            return

        self.update_status()

    # ========== Minimax AI ==========
    def get_best_move(self):
        best_score = -float("inf")
        best_move = None

        for i in range(9):
            if self.board[i] == 0:
                self.board[i] = self.ai
                score = self.minimax(self.board, 0, False)
                self.board[i] = 0
                if score > best_score:
                    best_score = score
                    best_move = i

        return best_move

    def minimax(self, board, depth, is_maximizing):
        # 终局判断
        if self.check_win_static(board, self.ai):
            return 10 - depth
        if self.check_win_static(board, self.player):
            return depth - 10
        if self.is_full_static(board):
            return 0

        if is_maximizing:
            best = -float("inf")
            for i in range(9):
                if board[i] == 0:
                    board[i] = self.ai
                    best = max(best, self.minimax(board, depth + 1, False))
                    board[i] = 0
            return best
        else:
            best = float("inf")
            for i in range(9):
                if board[i] == 0:
                    board[i] = self.player
                    best = min(best, self.minimax(board, depth + 1, True))
                    board[i] = 0
            return best

    # ========== 工具函数 ==========
    def check_win(self, player):
        return self.check_win_static(self.board, player)

    def check_win_static(self, board, player):
        lines = [
            [0,1,2],[3,4,5],[6,7,8],  # 行
            [0,3,6],[1,4,7],[2,5,8],  # 列
            [0,4,8],[2,4,6]              # 对角线
        ]
        return any(all(board[i] == player for i in line) for line in lines)

    def is_full(self):
        return self.is_full_static(self.board)

    def is_full_static(self, board):
        return all(x != 0 for x in board)

    def end_game(self, msg):
        self.game_over = True
        self.status_label.config(text=msg)
        self.update_stat()
        messagebox.showinfo("游戏结束", msg)

    def update_status(self):
        self.status_label.config(text="你的回合（❌）")
        self.update_stat()

    def update_stat(self):
        self.stat_label.config(
            text="胜：" + str(self.wins) +
            "  负：" + str(self.losses) +
            "  平：" + str(self.draws)
        )

    def reset_game(self):
        self.board = [0] * 9
        self.game_over = False
        for btn in self.buttons:
            btn.config(text="", state="normal")
        self.update_status()


if __name__ == "__main__":
    root = tk.Tk()
    TicTacToeAI(root)
    root.mainloop()