import tkinter as tk
from tkinter import messagebox, font
import random
import time

# ============ 题目池 ============
QUESTIONS = [
    # (显示文本, 正确答案)
    ("42", "int"),
    ("-17", "int"),
    ("3.14", "float"),
    ("-0.5", "float"),
    ("2e10", "float"),
    ('"hello"', "str"),
    ("'Python'", "str"),
    ('"True"', "str"),          # 注意：带引号的是字符串！
    ("True", "bool"),
    ("False", "bool"),
    ("[1, 2, 3]", "list"),
    ("[]", "list"),
    ("{'name': 'Tom'}", "dict"),
    ("{}", "dict"),             # 空字典
    ("None", "None"),
]

TYPE_BUTTONS = ["int", "float", "str", "bool", "list", "dict", "None"]

# 颜色方案
COLORS = {
    "bg": "#2C3E50",
    "hole": "#5D4037",
    "mole": "#8D6E63",
    "mole_hit": "#FF5722",
    "text": "#FFFFFF",
    "accent": "#FFC107",
    "btn_int": "#E53935",
    "btn_float": "#8E24AA",
    "btn_str": "#43A047",
    "btn_bool": "#FB8C00",
    "btn_list": "#1E88E5",
    "btn_dict": "#00ACC1",
    "btn_None": "#757575",
}

MOLE_APPEAR_TIME = 2.5  # 每个地鼠停留秒数


class WhackTypeGame:
    def __init__(self, root):
        self.root = root
        self.root.title("🔨 打地鼠 · 数据类型识别版")
        self.root.geometry("700x600")
        self.root.resizable(False, False)
        self.root.configure(bg=COLORS["bg"])

        self.score = 0
        self.lives = 3
        self.current_mole = None
        self.mole_start_time = 0
        self.game_running = False
        self.after_id = None

        self._build_ui()
        self._start_game()

    # ============ 界面构建 ============
    def _build_ui(self):
        # ---- 顶部信息栏 ----
        top_frame = tk.Frame(self.root, bg=COLORS["bg"])
        top_frame.pack(pady=10)

        self.score_label = tk.Label(
            top_frame, text="得分: 0", font=("Arial", 16, "bold"),
            fg=COLORS["accent"], bg=COLORS["bg"]
        )
        self.score_label.pack(side=tk.LEFT, padx=30)

        self.lives_label = tk.Label(
            top_frame, text="❤️❤️❤️", font=("Arial", 16),
            fg="#E53935", bg=COLORS["bg"]
        )
        self.lives_label.pack(side=tk.LEFT, padx=30)

        self.timer_label = tk.Label(
            top_frame, text="⏱ 2.5s", font=("Arial", 14),
            fg=COLORS["text"], bg=COLORS["bg"]
        )
        self.timer_label.pack(side=tk.LEFT, padx=30)

        # ---- 游戏区域 ----
        game_frame = tk.Frame(self.root, bg=COLORS["bg"])
        game_frame.pack(pady=20)

        # 洞口
        self.hole_canvas = tk.Canvas(
            game_frame, width=200, height=180,
            bg=COLORS["bg"], highlightthickness=0
        )
        self.hole_canvas.pack()

        # 画洞口
        self.hole_canvas.create_oval(30, 80, 170, 170, fill=COLORS["hole"], outline="")
        self.hole_canvas.create_oval(40, 90, 160, 160, fill="#3E2723", outline="")

        # 地鼠（初始隐藏）
        self.mole_body = self.hole_canvas.create_oval(
            55, 30, 145, 110, fill=COLORS["mole"], outline="", state="hidden"
        )
        self.mole_eye_l = self.hole_canvas.create_oval(
            75, 50, 85, 60, fill="white", state="hidden"
        )
        self.mole_eye_r = self.hole_canvas.create_oval(
            115, 50, 125, 60, fill="white", state="hidden"
        )
        self.mole_value_text = self.hole_canvas.create_text(
            100, 75, text="", font=("Consolas", 12, "bold"),
            fill="white", state="hidden"
        )

        # 打飞动画用的
        self.fly_text = self.hole_canvas.create_text(
            100, 20, text="💥", font=("Arial", 24), state="hidden"
        )

        # ---- 题目提示 ----
        self.question_label = tk.Label(
            self.root, text="判断地鼠身上的数据类型！",
            font=("Arial", 13), fg=COLORS["text"], bg=COLORS["bg"]
        )
        self.question_label.pack(pady=5)

        # ---- 按钮区域 ----
        btn_frame = tk.Frame(self.root, bg=COLORS["bg"])
        btn_frame.pack(pady=10)

        self.type_buttons = {}
        for i, t in enumerate(TYPE_BUTTONS):
            btn_color = COLORS.get(f"btn_{t}", "#757575")
            btn = tk.Button(
                btn_frame, text=t,
                font=("Arial", 13, "bold"),
                fg="white", bg=btn_color,
                width=7, height=2,
                command=lambda typ=t: self._on_answer(typ),
                cursor="hand2", relief="flat"
            )
            btn.grid(row=i // 4, column=i % 4, padx=6, pady=5)
            self.type_buttons[t] = btn

        # ---- 底部提示 ----
        hint_text = (
            "💡 提示：带引号的如 'hello' 是 str，不带引号的数字看有没有小数点，"
            "True/False 是 bool，[] 是 list，{} 是 dict，None 是空值"
        )
        tk.Label(
            self.root, text=hint_text, font=("Arial", 9),
            fg="#B0BEC5", bg=COLORS["bg"], wraplength=650
        ).pack(pady=8)

    # ============ 游戏逻辑 ============
    def _start_game(self):
        self.score = 0
        self.lives = 3
        self.game_running = True
        self._update_score_display()
        self._spawn_mole()

    def _spawn_mole(self):
        if not self.game_running:
            return

        self.current_mole = random.choice(QUESTIONS)
        value_text, correct_type = self.current_mole

        # 显示地鼠
        self.hole_canvas.itemconfig(self.mole_body, state="normal", fill=COLORS["mole"])
        self.hole_canvas.itemconfig(self.mole_eye_l, state="normal")
        self.hole_canvas.itemconfig(self.mole_eye_r, state="normal")
        self.hole_canvas.itemconfig(self.mole_value_text, state="normal", text=value_text)
        self.hole_canvas.itemconfig(self.fly_text, state="hidden")

        self.mole_start_time = time.time()

        # 启动计时器更新
        self._update_timer()

        # 设置超时
        self.after_id = self.root.after(int(MOLE_APPEAR_TIME * 1000), self._mole_timeout)

    def _update_timer(self):
        if not self.game_running or not self.current_mole:
            return
        elapsed = time.time() - self.mole_start_time
        remaining = max(0, MOLE_APPEAR_TIME - elapsed)
        self.timer_label.config(text=f"⏱ {remaining:.1f}s")

        if remaining > 0:
            self.root.after(100, self._update_timer)

    def _mole_timeout(self):
        if not self.game_running:
            return
        # 时间到没打 → 扣命
        self.lives -= 1
        self._update_score_display()
        self._hide_mole()

        if self.lives <= 0:
            self._game_over()
        else:
            self.root.after(500, self._spawn_mole)

    def _on_answer(self, chosen_type):
        if not self.game_running or not self.current_mole:
            return

        # 取消超时计时
        if self.after_id:
            self.root.after_cancel(self.after_id)

        value_text, correct_type = self.current_mole

        if chosen_type == correct_type:
            # ✅ 正确
            self.score += 1
            self._show_feedback(True)
        else:
            # ❌ 错误
            self.lives -= 1
            self._show_feedback(False, correct_type)

        self._update_score_display()
        self._hide_mole()

        if self.lives <= 0:
            self.root.after(600, self._game_over)
        else:
            self.root.after(600, self._spawn_mole)

    def _show_feedback(self, correct, correct_type=""):
        if correct:
            self.hole_canvas.itemconfig(self.fly_text, state="normal", text="✅ +1")
            self.hole_canvas.itemconfig(self.mole_body, fill="#4CAF50")
        else:
            self.hole_canvas.itemconfig(self.fly_text, state="normal", text=f"❌ 是 {correct_type}")
            self.hole_canvas.itemconfig(self.mole_body, fill="#F44336")

    def _hide_mole(self):
        self.hole_canvas.itemconfig(self.mole_body, state="hidden")
        self.hole_canvas.itemconfig(self.mole_eye_l, state="hidden")
        self.hole_canvas.itemconfig(self.mole_eye_r, state="hidden")
        self.hole_canvas.itemconfig(self.mole_value_text, state="hidden")

    def _update_score_display(self):
        self.score_label.config(text=f"得分: {self.score}")
        hearts = "❤️" * self.lives + "🖤" * (3 - self.lives)
        self.lives_label.config(text=hearts)

    def _game_over(self):
        self.game_running = False
        self.timer_label.config(text="⏱ 0.0s")
        messagebox.showinfo(
            "游戏结束",
            f"🎮 游戏结束！\n\n最终得分: {self.score}\n\n"
            f"{'🏆 太强了！' if self.score >= 10 else '💪 继续加油！'}"
        )
        # 询问是否重玩
        if messagebox.askyesno("再来一局？", "要重新开始吗？"):
            self._start_game()


# ============ 启动 ============
if __name__ == "__main__":
    root = tk.Tk()
    app = WhackTypeGame(root)
    root.mainloop()