import tkinter as tk
import random
import time

class ReactionGame:
    def __init__(self, master):
        self.master = master
        self.master.title("反应速度测试 — 点击圆点")
        self.master.resizable(False, False)

        # 画布大小
        self.canvas_width = 600
        self.canvas_height = 400
        self.canvas = tk.Canvas(
            master,
            width=self.canvas_width,
            height=self.canvas_height,
            bg='white',
            highlightthickness=0
        )
        self.canvas.pack(pady=10)

        # 信息栏
        info_frame = tk.Frame(master)
        info_frame.pack()

        self.score_label = tk.Label(info_frame, text="得分: 0", font=("Arial", 12))
        self.score_label.pack(side=tk.LEFT, padx=10)

        self.reaction_label = tk.Label(
            info_frame, text="上次反应: -- ms", font=("Arial", 12)
        )
        self.reaction_label.pack(side=tk.LEFT, padx=10)

        self.avg_label = tk.Label(
            info_frame, text="平均反应: -- ms", font=("Arial", 12)
        )
        self.avg_label.pack(side=tk.LEFT, padx=10)

        self.time_label = tk.Label(info_frame, text="剩余时间: 30 s", font=("Arial", 12))
        self.time_label.pack(side=tk.LEFT, padx=10)

        # 按钮
        btn_frame = tk.Frame(master)
        btn_frame.pack(pady=5)
        self.start_btn = tk.Button(btn_frame, text="开始", command=self.start_game, width=8)
        self.start_btn.pack(side=tk.LEFT, padx=10)
        self.reset_btn = tk.Button(btn_frame, text="重置", command=self.reset_game, width=8, state=tk.DISABLED)
        self.reset_btn.pack(side=tk.LEFT, padx=10)

        # 游戏状态
        self.game_duration = 30          # 游戏时长（秒）
        self.remaining = self.game_duration
        self.game_active = False
        self.score = 0
        self.total_reaction_time = 0.0
        self.num_clicks = 0
        self.target_time = None
        self.target_radius = 22          # 圆点半径

    def start_game(self):
        """开始新一局游戏"""
        self.game_active = True
        self.start_btn.config(state=tk.DISABLED)
        self.reset_btn.config(state=tk.NORMAL)

        # 重置数据
        self.score = 0
        self.total_reaction_time = 0.0
        self.num_clicks = 0
        self.remaining = self.game_duration

        self.update_labels()
        self.spawn_target()
        self.tick()

    def reset_game(self):
        """重置界面，停止游戏"""
        self.game_active = False
        self.canvas.delete("target")
        self.start_btn.config(state=tk.NORMAL)
        self.reset_btn.config(state=tk.DISABLED)

        self.score = 0
        self.total_reaction_time = 0.0
        self.num_clicks = 0
        self.remaining = self.game_duration

        self.update_labels()
        self.time_label.config(text=f"剩余时间: {self.remaining} s")

    def spawn_target(self):
        """在随机位置生成一个新的红色圆点"""
        if not self.game_active:
            return
        self.canvas.delete("target")
        margin = self.target_radius + 5
        x = random.randint(margin, self.canvas_width - margin)
        y = random.randint(margin, self.canvas_height - margin)
        self.canvas.create_oval(
            x - self.target_radius, y - self.target_radius,
            x + self.target_radius, y + self.target_radius,
            fill='red', outline='darkred', width=2, tags="target"
        )
        self.canvas.tag_bind("target", "<Button-1>", self.on_hit)
        self.target_time = time.time()   # 记录出现时刻

    def on_hit(self, event):
        """点击圆点时的处理"""
        if not self.game_active:
            return
        reaction = time.time() - self.target_time   # 反应时间（秒）
        self.total_reaction_time += reaction
        self.num_clicks += 1
        self.score += 1

        # 显示上次反应时间（毫秒）
        last_ms = reaction * 1000
        self.reaction_label.config(text=f"上次反应: {last_ms:.0f} ms")

        self.update_labels()
        self.spawn_target()   # 立即生成下一个圆点

    def tick(self):
        """每秒更新倒计时"""
        if not self.game_active:
            return
        self.remaining -= 1
        self.time_label.config(text=f"剩余时间: {self.remaining} s")
        if self.remaining <= 0:
            self.end_game()
        else:
            self.master.after(1000, self.tick)

    def end_game(self):
        """时间到，结束游戏"""
        self.game_active = False
        self.canvas.delete("target")
        self.start_btn.config(state=tk.NORMAL)
        self.reset_btn.config(state=tk.NORMAL)
        self.time_label.config(text="时间到！")

        if self.num_clicks > 0:
            avg_ms = (self.total_reaction_time / self.num_clicks) * 1000
            self.avg_label.config(text=f"平均反应: {avg_ms:.0f} ms")
        else:
            self.avg_label.config(text="平均反应: -- ms")

    def update_labels(self):
        """更新得分和平均反应时间显示"""
        self.score_label.config(text=f"得分: {self.score}")
        if self.num_clicks > 0:
            avg_ms = (self.total_reaction_time / self.num_clicks) * 1000
            self.avg_label.config(text=f"平均反应: {avg_ms:.0f} ms")
        else:
            self.avg_label.config(text="平均反应: -- ms")


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