import tkinter as tk
from tkinter import ttk, messagebox
import random
from typing import List, Tuple
from PIL import Image, ImageTk
import os
from dataclasses import dataclass
from datetime import datetime

@dataclass
class GameResult:
    """游戏结果"""
    player_choice: str
    computer_choice: str
    result: str
    timestamp: datetime

class RockPaperScissorsGame:
    def __init__(self, root):
        self.root = root
        self.root.title("✊✂️✋ 石头剪刀布游戏")
        
        # 窗口设置
        self.width = 900
        self.height = 600
        self.root.geometry(f"{self.width}x{self.height}")
        self.root.configure(bg='#f0f8ff')
        
        # 游戏选项
        self.choices = ["石头", "剪刀", "布"]
        self.choice_icons = {"石头": "✊", "剪刀": "✂️", "布": "✋"}
        self.choice_colors = {
            "石头": "#3498db",  # 蓝色
            "剪刀": "#e74c3c",  # 红色
            "布": "#2ecc71"     # 绿色
        }
        
        # 游戏规则
        self.rules = {
            ("石头", "剪刀"): "win",    # 石头赢剪刀
            ("剪刀", "布"): "win",      # 剪刀赢布
            ("布", "石头"): "win",      # 布赢石头
            ("剪刀", "石头"): "lose",   # 剪刀输石头
            ("布", "剪刀"): "lose",    # 布输剪刀
            ("石头", "布"): "lose",    # 石头输布
        }
        
        # 游戏统计
        self.stats = {
            "total_games": 0,
            "wins": 0,
            "losses": 0,
            "draws": 0,
            "win_streak": 0,
            "max_streak": 0
        }
        
        # 游戏历史
        self.history: List[GameResult] = []
        
        # 当前状态
        self.player_choice = None
        self.computer_choice = None
        self.game_result = None
        self.animation_running = False
        
        # 加载图片
        self.load_images()
        
        # 创建界面
        self.create_ui()
        
        # 绑定快捷键
        self.bind_shortcuts()
    
    def load_images(self):
        """加载图片资源"""
        try:
            # 尝试加载图片，如果不存在则使用默认图标
            image_size = (120, 120)
            
            # 石头图片
            rock_img = Image.new('RGBA', image_size, (52, 152, 219, 255))
            self.rock_photo = ImageTk.PhotoImage(rock_img)
            
            # 剪刀图片
            scissor_img = Image.new('RGBA', image_size, (231, 76, 60, 255))
            self.scissor_photo = ImageTk.PhotoImage(scissor_img)
            
            # 布图片
            paper_img = Image.new('RGBA', image_size, (46, 204, 113, 255))
            self.paper_photo = ImageTk.PhotoImage(paper_img)
            
            # 问号图片（默认）
            question_img = Image.new('RGBA', image_size, (149, 165, 166, 255))
            self.question_photo = ImageTk.PhotoImage(question_img)
            
        except:
            # 如果图片加载失败，使用文本
            self.rock_photo = None
            self.scissor_photo = None
            self.paper_photo = None
            self.question_photo = None
    
    def create_ui(self):
        """创建用户界面"""
        # 主框架
        main_frame = tk.Frame(self.root, bg='#f0f8ff', padx=20, pady=20)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题栏
        self.create_header(main_frame)
        
        # 游戏区域
        self.create_game_area(main_frame)
        
        # 控制区域
        self.create_control_area(main_frame)
        
        # 统计区域
        self.create_stats_area(main_frame)
        
        # 状态栏
        self.create_statusbar(main_frame)
    
    def create_header(self, parent):
        """创建标题栏"""
        header_frame = tk.Frame(parent, bg='#f0f8ff')
        header_frame.pack(fill=tk.X, pady=(0, 20))
        
        # 游戏标题
        title_label = tk.Label(header_frame, 
                              text="✊✂️✋ 石头剪刀布游戏", 
                              font=("Microsoft YaHei", 28, "bold"),
                              fg="#2c3e50", bg='#f0f8ff')
        title_label.pack()
        
        # 游戏说明
        desc_label = tk.Label(header_frame, 
                             text="规则：石头赢剪刀，剪刀赢布，布赢石头", 
                             font=("Microsoft YaHei", 12),
                             fg="#7f8c8d", bg='#f0f8ff')
        desc_label.pack()
    
    def create_game_area(self, parent):
        """创建游戏区域"""
        game_frame = tk.Frame(parent, bg='#f0f8ff')
        game_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 20))
        
        # 玩家区域
        player_frame = tk.LabelFrame(game_frame, text="👤 玩家", 
                                    font=("Microsoft YaHei", 16, "bold"),
                                    bg='white', fg="#3498db",
                                    padx=20, pady=20)
        player_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
        
        # 玩家选择显示
        self.player_frame_inner = tk.Frame(player_frame, bg='white')
        self.player_frame_inner.pack(fill=tk.BOTH, expand=True)
        
        self.player_label = tk.Label(self.player_frame_inner, text="?", 
                                    font=("Arial", 100, "bold"),
                                    fg="#3498db", bg='white')
        self.player_label.pack(expand=True)
        
        self.player_text = tk.Label(self.player_frame_inner, text="等待选择...", 
                                   font=("Microsoft YaHei", 16),
                                   fg="#7f8c8d", bg='white')
        self.player_text.pack()
        
        # VS 区域
        vs_frame = tk.Frame(game_frame, bg='#f0f8ff', width=100)
        vs_frame.pack(side=tk.LEFT, fill=tk.Y)
        vs_frame.pack_propagate(False)
        
        vs_label = tk.Label(vs_frame, text="VS", 
                          font=("Microsoft YaHei", 36, "bold"),
                          fg="#e74c3c", bg='#f0f8ff')
        vs_label.pack(expand=True)
        
        # 电脑区域
        computer_frame = tk.LabelFrame(game_frame, text="🤖 电脑", 
                                      font=("Microsoft YaHei", 16, "bold"),
                                      bg='white', fg="#e74c3c",
                                      padx=20, pady=20)
        computer_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))
        
        # 电脑选择显示
        self.computer_frame_inner = tk.Frame(computer_frame, bg='white')
        self.computer_frame_inner.pack(fill=tk.BOTH, expand=True)
        
        self.computer_label = tk.Label(self.computer_frame_inner, text="?", 
                                      font=("Arial", 100, "bold"),
                                      fg="#e74c3c", bg='white')
        self.computer_label.pack(expand=True)
        
        self.computer_text = tk.Label(self.computer_frame_inner, text="等待选择...", 
                                     font=("Microsoft YaHei", 16),
                                     fg="#7f8c8d", bg='white')
        self.computer_text.pack()
    
    def create_control_area(self, parent):
        """创建控制区域"""
        control_frame = tk.Frame(parent, bg='#f0f8ff')
        control_frame.pack(fill=tk.X, pady=(0, 20))
        
        # 选择按钮
        btn_frame = tk.Frame(control_frame, bg='#f0f8ff')
        btn_frame.pack()
        
        # 石头按钮
        self.rock_btn = tk.Button(btn_frame, text="✊ 石头", 
                                 command=lambda: self.player_choose("石头"),
                                 font=("Microsoft YaHei", 20, "bold"),
                                 bg="#3498db", fg="white",
                                 relief=tk.RAISED, bd=3,
                                 width=10, height=2)
        self.rock_btn.grid(row=0, column=0, padx=10, pady=5)
        
        # 剪刀按钮
        self.scissor_btn = tk.Button(btn_frame, text="✂️ 剪刀", 
                                    command=lambda: self.player_choose("剪刀"),
                                    font=("Microsoft YaHei", 20, "bold"),
                                    bg="#e74c3c", fg="white",
                                    relief=tk.RAISED, bd=3,
                                    width=10, height=2)
        self.scissor_btn.grid(row=0, column=1, padx=10, pady=5)
        
        # 布按钮
        self.paper_btn = tk.Button(btn_frame, text="✋ 布", 
                                  command=lambda: self.player_choose("布"),
                                  font=("Microsoft YaHei", 20, "bold"),
                                  bg="#2ecc71", fg="white",
                                  relief=tk.RAISED, bd=3,
                                  width=10, height=2)
        self.paper_btn.grid(row=0, column=2, padx=10, pady=5)
        
        # 控制按钮
        ctrl_frame = tk.Frame(control_frame, bg='#f0f8ff')
        ctrl_frame.pack(pady=10)
        
        # 随机选择按钮
        random_btn = tk.Button(ctrl_frame, text="🎲 随机选择", 
                              command=self.random_choose,
                              font=("Microsoft YaHei", 12),
                              bg="#9b59b6", fg="white",
                              relief=tk.FLAT, width=12)
        random_btn.pack(side=tk.LEFT, padx=5)
        
        # 重新开始按钮
        restart_btn = tk.Button(ctrl_frame, text="🔄 重新开始", 
                               command=self.restart_game,
                               font=("Microsoft YaHei", 12),
                               bg="#f39c12", fg="white",
                               relief=tk.FLAT, width=12)
        restart_btn.pack(side=tk.LEFT, padx=5)
        
        # 清空历史按钮
        clear_btn = tk.Button(ctrl_frame, text="🧹 清空历史", 
                             command=self.clear_history,
                             font=("Microsoft YaHei", 12),
                             bg="#e74c3c", fg="white",
                             relief=tk.FLAT, width=12)
        clear_btn.pack(side=tk.LEFT, padx=5)
        
        # 结果区域
        result_frame = tk.Frame(control_frame, bg='#f0f8ff')
        result_frame.pack(pady=10)
        
        self.result_label = tk.Label(result_frame, text="", 
                                    font=("Microsoft YaHei", 18, "bold"),
                                    bg='#f0f8ff')
        self.result_label.pack()
    
    def create_stats_area(self, parent):
        """创建统计区域"""
        stats_frame = tk.LabelFrame(parent, text="📊 游戏统计", 
                                   font=("Microsoft YaHei", 14, "bold"),
                                   bg='white', fg="#2c3e50",
                                   padx=20, pady=20)
        stats_frame.pack(fill=tk.X)
        
        # 统计数据
        stats_grid = tk.Frame(stats_frame, bg='white')
        stats_grid.pack()
        
        # 总场数
        tk.Label(stats_grid, text="总场数:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#34495e").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.total_games_label = tk.Label(stats_grid, text="0", 
                                         font=("Microsoft YaHei", 12, "bold"),
                                         bg='white', fg="#2c3e50")
        self.total_games_label.grid(row=0, column=1, sticky=tk.W, pady=5, padx=10)
        
        # 胜场
        tk.Label(stats_grid, text="胜场:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#2ecc71").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.wins_label = tk.Label(stats_grid, text="0", 
                                  font=("Microsoft YaHei", 12, "bold"),
                                  bg='white', fg="#2ecc71")
        self.wins_label.grid(row=1, column=1, sticky=tk.W, pady=5, padx=10)
        
        # 负场
        tk.Label(stats_grid, text="负场:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#e74c3c").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.losses_label = tk.Label(stats_grid, text="0", 
                                    font=("Microsoft YaHei", 12, "bold"),
                                    bg='white', fg="#e74c3c")
        self.losses_label.grid(row=2, column=1, sticky=tk.W, pady=5, padx=10)
        
        # 平局
        tk.Label(stats_grid, text="平局:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#f39c12").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.draws_label = tk.Label(stats_grid, text="0", 
                                   font=("Microsoft YaHei", 12, "bold"),
                                   bg='white', fg="#f39c12")
        self.draws_label.grid(row=3, column=1, sticky=tk.W, pady=5, padx=10)
        
        # 胜率
        tk.Label(stats_grid, text="胜率:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#3498db").grid(row=0, column=2, sticky=tk.W, pady=5, padx=(30, 0))
        self.win_rate_label = tk.Label(stats_grid, text="0%", 
                                      font=("Microsoft YaHei", 12, "bold"),
                                      bg='white', fg="#3498db")
        self.win_rate_label.grid(row=0, column=3, sticky=tk.W, pady=5, padx=10)
        
        # 连胜
        tk.Label(stats_grid, text="当前连胜:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#9b59b6").grid(row=1, column=2, sticky=tk.W, pady=5, padx=(30, 0))
        self.streak_label = tk.Label(stats_grid, text="0", 
                                    font=("Microsoft YaHei", 12, "bold"),
                                    bg='white', fg="#9b59b6")
        self.streak_label.grid(row=1, column=3, sticky=tk.W, pady=5, padx=10)
        
        # 最大连胜
        tk.Label(stats_grid, text="最大连胜:", 
                font=("Microsoft YaHei", 12),
                bg='white', fg="#1abc9c").grid(row=2, column=2, sticky=tk.W, pady=5, padx=(30, 0))
        self.max_streak_label = tk.Label(stats_grid, text="0", 
                                        font=("Microsoft YaHei", 12, "bold"),
                                        bg='white', fg="#1abc9c")
        self.max_streak_label.grid(row=2, column=3, sticky=tk.W, pady=5, padx=10)
        
        # 历史记录
        history_frame = tk.Frame(stats_frame, bg='white')
        history_frame.pack(fill=tk.X, pady=(10, 0))
        
        tk.Label(history_frame, text="最近记录:", 
                font=("Microsoft YaHei", 12, "bold"),
                bg='white', fg="#34495e").pack(anchor=tk.W)
        
        self.history_text = tk.Text(history_frame, height=4, width=50,
                                   font=("Microsoft YaHei", 10),
                                   bg='#f8f9fa', fg="#2c3e50",
                                   state=tk.DISABLED)
        scrollbar = tk.Scrollbar(history_frame, orient=tk.VERTICAL)
        self.history_text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.history_text.yview)
        
        self.history_text.pack(side=tk.LEFT, fill=tk.X, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    def create_statusbar(self, parent):
        """创建状态栏"""
        status_frame = tk.Frame(parent, bg='#ecf0f1', height=30)
        status_frame.pack(fill=tk.X, pady=(20, 0))
        status_frame.pack_propagate(False)
        
        self.status_label = tk.Label(status_frame, text="请选择：石头、剪刀或布", 
                                    font=("Microsoft YaHei", 10),
                                    fg="#7f8c8d", bg='#ecf0f1')
        self.status_label.pack(side=tk.LEFT, padx=10)
    
    def bind_shortcuts(self):
        """绑定快捷键"""
        self.root.bind('1', lambda e: self.player_choose("石头"))
        self.root.bind('2', lambda e: self.player_choose("剪刀"))
        self.root.bind('3', lambda e: self.player_choose("布"))
        self.root.bind('<space>', lambda e: self.random_choose())
        self.root.bind('<r>', lambda e: self.restart_game())
    
    def player_choose(self, choice):
        """玩家选择"""
        if self.animation_running:
            return
        
        self.player_choice = choice
        self.status_label.config(text=f"你选择了: {choice}")
        
        # 更新玩家显示
        self.update_player_display(choice)
        
        # 开始电脑选择动画
        self.start_computer_animation()
    
    def update_player_display(self, choice):
        """更新玩家显示"""
        icon = self.choice_icons[choice]
        color = self.choice_colors[choice]
        
        self.player_label.config(text=icon, fg=color)
        self.player_text.config(text=choice, fg=color)
    
    def update_computer_display(self, choice):
        """更新电脑显示"""
        icon = self.choice_icons[choice]
        color = self.choice_colors[choice]
        
        self.computer_label.config(text=icon, fg=color)
        self.computer_text.config(text=choice, fg=color)
    
    def start_computer_animation(self):
        """开始电脑选择动画"""
        self.animation_running = True
        self.computer_choice = None
        
        # 禁用按钮
        self.rock_btn.config(state=tk.DISABLED)
        self.scissor_btn.config(state=tk.DISABLED)
        self.paper_btn.config(state=tk.DISABLED)
        
        # 动画循环
        self.animation_count = 0
        self.animate_computer()
    
    def animate_computer(self, count=0):
        """电脑选择动画"""
        if count >= 10:  # 动画10次
            # 生成电脑选择
            self.computer_choice = random.choice(self.choices)
            self.update_computer_display(self.computer_choice)
            
            # 判断胜负
            self.determine_winner()
            
            # 启用按钮
            self.rock_btn.config(state=tk.NORMAL)
            self.scissor_btn.config(state=tk.NORMAL)
            self.paper_btn.config(state=tk.NORMAL)
            
            self.animation_running = False
            return
        
        # 显示随机选择
        choice = random.choice(self.choices)
        icon = self.choice_icons[choice]
        self.computer_label.config(text=icon)
        self.computer_text.config(text="...")
        
        # 继续动画
        self.root.after(100, lambda: self.animate_computer(count + 1))
    
    def determine_winner(self):
        """判断胜负"""
        if self.player_choice == self.computer_choice:
            result = "平局"
            result_color = "#f39c12"
            result_icon = "🤝"
        elif (self.player_choice, self.computer_choice) in self.rules and \
             self.rules[(self.player_choice, self.computer_choice)] == "win":
            result = "你赢了！"
            result_color = "#2ecc71"
            result_icon = "🎉"
        else:
            result = "你输了！"
            result_color = "#e74c3c"
            result_icon = "😢"
        
        # 更新结果显示
        self.result_label.config(text=f"{result_icon} {result}", fg=result_color)
        
        # 更新统计
        self.update_stats(result)
        
        # 保存到历史
        self.save_to_history(result)
        
        # 更新状态
        self.status_label.config(text=f"结果: {result}")
    
    def update_stats(self, result):
        """更新统计"""
        self.stats["total_games"] += 1
        
        if result == "你赢了！":
            self.stats["wins"] += 1
            self.stats["win_streak"] += 1
            if self.stats["win_streak"] > self.stats["max_streak"]:
                self.stats["max_streak"] = self.stats["win_streak"]
        elif result == "你输了！":
            self.stats["losses"] += 1
            self.stats["win_streak"] = 0
        else:  # 平局
            self.stats["draws"] += 1
        
        # 计算胜率
        if self.stats["total_games"] > 0:
            win_rate = (self.stats["wins"] / self.stats["total_games"]) * 100
        else:
            win_rate = 0
        
        # 更新标签
        self.total_games_label.config(text=str(self.stats["total_games"]))
        self.wins_label.config(text=str(self.stats["wins"]))
        self.losses_label.config(text=str(self.stats["losses"]))
        self.draws_label.config(text=str(self.stats["draws"]))
        self.win_rate_label.config(text=f"{win_rate:.1f}%")
        self.streak_label.config(text=str(self.stats["win_streak"]))
        self.max_streak_label.config(text=str(self.stats["max_streak"]))
    
    def save_to_history(self, result):
        """保存到历史记录"""
        game_result = GameResult(
            player_choice=self.player_choice,
            computer_choice=self.computer_choice,
            result=result,
            timestamp=datetime.now()
        )
        self.history.append(game_result)
        
        # 只保留最近10条记录
        if len(self.history) > 10:
            self.history = self.history[-10:]
        
        # 更新历史显示
        self.update_history_display()
    
    def update_history_display(self):
        """更新历史记录显示"""
        self.history_text.config(state=tk.NORMAL)
        self.history_text.delete(1.0, tk.END)
        
        for i, record in enumerate(reversed(self.history[-5:]), 1):
            time_str = record.timestamp.strftime("%H:%M")
            player_icon = self.choice_icons[record.player_choice]
            computer_icon = self.choice_icons[record.computer_choice]
            
            if record.result == "你赢了！":
                result_icon = "✅"
            elif record.result == "你输了！":
                result_icon = "❌"
            else:
                result_icon = "⚪"
            
            history_line = f"{time_str}  {player_icon} vs {computer_icon}  {result_icon}  {record.result}\n"
            self.history_text.insert(tk.END, history_line)
        
        self.history_text.config(state=tk.DISABLED)
    
    def random_choose(self):
        """随机选择"""
        if self.animation_running:
            return
        
        choice = random.choice(self.choices)
        self.player_choose(choice)
    
    def restart_game(self):
        """重新开始游戏"""
        if self.animation_running:
            return
        
        # 重置当前游戏
        self.player_choice = None
        self.computer_choice = None
        self.game_result = None
        
        # 重置显示
        self.player_label.config(text="?", fg="#3498db")
        self.player_text.config(text="等待选择...", fg="#7f8c8d")
        
        self.computer_label.config(text="?", fg="#e74c3c")
        self.computer_text.config(text="等待选择...", fg="#7f8c8d")
        
        self.result_label.config(text="")
        self.status_label.config(text="请选择：石头、剪刀或布")
        
        # 启用按钮
        self.rock_btn.config(state=tk.NORMAL)
        self.scissor_btn.config(state=tk.NORMAL)
        self.paper_btn.config(state=tk.NORMAL)
    
    def clear_history(self):
        """清空历史记录"""
        if messagebox.askyesno("确认", "确定要清空历史记录吗？"):
            self.history = []
            self.update_history_display()
            self.status_label.config(text="历史记录已清空")

def main():
    """主函数"""
    root = tk.Tk()
    
    # 设置窗口居中
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    width = 900
    height = 600
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2
    root.geometry(f"{width}x{height}+{x}+{y}")
    
    app = RockPaperScissorsGame(root)
    root.mainloop()

if __name__ == "__main__":
    main()