import tkinter as tk
from tkinter import ttk, messagebox
import random
import time
from PIL import Image, ImageTk
import os
import json
from datetime import datetime
import pygame
import threading

# 初始化pygame mixer用于音效
try:
    pygame.mixer.init()
except:
    pass

class RockPaperScissorsGame:
    def __init__(self, root):
        self.root = root
        self.root.title("🎮 石头剪刀布游戏 v2.0")
        self.root.geometry("800x600")
        
        # 颜色方案
        self.colors = {
            'primary': '#3498db',
            'secondary': '#2c3e50',
            'success': '#2ecc71',
            'warning': '#f39c12',
            'danger': '#e74c3c',
            'light': '#ecf0f1',
            'dark': '#34495e',
            'rock': '#95a5a6',
            'paper': '#3498db',
            'scissors': '#e74c3c',
            'bg': '#f5f7fa'
        }
        
        # 游戏状态
        self.player_score = 0
        self.computer_score = 0
        self.draw_count = 0
        self.total_games = 0
        self.player_choice = None
        self.computer_choice = None
        self.game_in_progress = False
        self.current_round = 0
        self.max_rounds = 5
        self.game_history = []
        
        # 加载游戏数据
        self.load_game_data()
        
        # 加载图片资源
        self.load_images()
        
        # 加载音效
        self.load_sounds()
        
        # 创建UI
        self.setup_ui()
        
        # 显示开始界面
        self.show_start_screen()
        
    def load_images(self):
        """加载图片资源"""
        try:
            # 创建图片字典
            self.images = {}
            
            # 创建简单的图形
            self.create_placeholder_images()
            
        except Exception as e:
            print(f"加载图片失败: {e}")
            self.create_placeholder_images()
            
    def create_placeholder_images(self):
        """创建占位图片"""
        self.images = {}
        
        # 石头
        rock_img = Image.new('RGB', (150, 150), self.colors['rock'])
        self.images['rock'] = ImageTk.PhotoImage(rock_img)
        
        # 布
        paper_img = Image.new('RGB', (150, 150), self.colors['paper'])
        self.images['paper'] = ImageTk.PhotoImage(paper_img)
        
        # 剪刀
        scissors_img = Image.new('RGB', (150, 150), self.colors['scissors'])
        self.images['scissors'] = ImageTk.PhotoImage(scissors_img)
        
        # 未知
        unknown_img = Image.new('RGB', (150, 150), self.colors['light'])
        self.images['unknown'] = ImageTk.PhotoImage(unknown_img)
        
    def load_sounds(self):
        """加载音效"""
        self.sounds = {}
        try:
            # 尝试加载声音文件
            sound_files = {
                'win': 'win.wav',
                'lose': 'lose.wav',
                'draw': 'draw.wav',
                'click': 'click.wav',
                'start': 'start.wav'
            }
            
            for name, filename in sound_files.items():
                if os.path.exists(filename):
                    self.sounds[name] = pygame.mixer.Sound(filename)
        except:
            # 如果没有声音文件，使用空字典
            self.sounds = {}
            
    def play_sound(self, sound_name):
        """播放音效"""
        if sound_name in self.sounds:
            try:
                self.sounds[sound_name].play()
            except:
                pass
                
    def setup_ui(self):
        """设置用户界面"""
        # 设置背景色
        self.root.configure(bg=self.colors['bg'])
        
        # 主框架
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 顶部标题
        self.title_label = tk.Label(self.main_frame, text="🎮 石头剪刀布", 
                                   font=('Microsoft YaHei', 28, 'bold'),
                                   fg=self.colors['secondary'],
                                   bg=self.colors['bg'])
        self.title_label.pack(pady=(0, 20))
        
        # 游戏状态显示
        self.status_frame = ttk.Frame(self.main_frame)
        self.status_frame.pack(fill=tk.X, pady=(0, 20))
        
        # 玩家状态
        self.player_frame = ttk.LabelFrame(self.status_frame, text="玩家", padding=10)
        self.player_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
        
        self.player_label = tk.Label(self.player_frame, text="?", 
                                    font=('Arial', 48, 'bold'),
                                    fg=self.colors['primary'])
        self.player_label.pack()
        
        self.player_score_label = tk.Label(self.player_frame, text="分数: 0", 
                                          font=('Microsoft YaHei', 12))
        self.player_score_label.pack()
        
        # VS标签
        self.vs_label = tk.Label(self.status_frame, text="VS", 
                                font=('Arial', 24, 'bold'),
                                fg=self.colors['warning'],
                                bg=self.colors['bg'])
        self.vs_label.pack(side=tk.LEFT, padx=20)
        
        # 电脑状态
        self.computer_frame = ttk.LabelFrame(self.status_frame, text="电脑", padding=10)
        self.computer_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))
        
        self.computer_label = tk.Label(self.computer_frame, text="?", 
                                      font=('Arial', 48, 'bold'),
                                      fg=self.colors['danger'])
        self.computer_label.pack()
        
        self.computer_score_label = tk.Label(self.computer_frame, text="分数: 0", 
                                           font=('Microsoft YaHei', 12))
        self.computer_score_label.pack()
        
        # 结果显示
        self.result_label = tk.Label(self.main_frame, text="请选择你的出拳！", 
                                    font=('Microsoft YaHei', 18),
                                    fg=self.colors['secondary'],
                                    bg=self.colors['bg'])
        self.result_label.pack(pady=(0, 20))
        
        # 出拳选择区域
        self.choice_frame = ttk.Frame(self.main_frame)
        self.choice_frame.pack(fill=tk.X, pady=(0, 20))
        
        # 创建选择按钮
        self.create_choice_buttons()
        
        # 控制按钮区域
        self.control_frame = ttk.Frame(self.main_frame)
        self.control_frame.pack(fill=tk.X, pady=(0, 20))
        
        ttk.Button(self.control_frame, text="重新开始", command=self.restart_game).pack(side=tk.LEFT, padx=5)
        ttk.Button(self.control_frame, text="查看统计", command=self.show_stats).pack(side=tk.LEFT, padx=5)
        ttk.Button(self.control_frame, text="游戏设置", command=self.show_settings).pack(side=tk.LEFT, padx=5)
        ttk.Button(self.control_frame, text="帮助", command=self.show_help).pack(side=tk.LEFT, padx=5)
        
        # 游戏信息显示
        self.info_frame = ttk.LabelFrame(self.main_frame, text="游戏信息", padding=10)
        self.info_frame.pack(fill=tk.BOTH, expand=True)
        
        self.info_text = tk.Text(self.info_frame, height=8, font=('Microsoft YaHei', 10))
        self.info_text.pack(fill=tk.BOTH, expand=True)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.info_text)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.info_text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.info_text.yview)
        
        # 禁用编辑
        self.info_text.config(state='disabled')
        
    def create_choice_buttons(self):
        """创建选择按钮"""
        choices = [
            ("✊ 石头", "rock", self.colors['rock']),
            ("✋ 布", "paper", self.colors['paper']),
            ("✌️ 剪刀", "scissors", self.colors['scissors'])
        ]
        
        for text, choice, color in choices:
            frame = ttk.Frame(self.choice_frame)
            frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5)
            
            # 创建按钮
            btn = tk.Button(frame, text=text, 
                           font=('Microsoft YaHei', 14, 'bold'),
                           bg=color, fg='white',
                           relief=tk.RAISED, borderwidth=3,
                           command=lambda c=choice: self.player_choose(c))
            btn.pack(fill=tk.BOTH, expand=True, ipady=10)
            
            # 鼠标悬停效果
            btn.bind("<Enter>", lambda e, b=btn, c=color: 
                    b.config(bg=self.adjust_color(c, 20)))
            btn.bind("<Leave>", lambda e, b=btn, c=color: 
                    b.config(bg=c))
            
    def adjust_color(self, color, delta):
        """调整颜色亮度"""
        # 简化版颜色调整
        return color
        
    def show_start_screen(self):
        """显示开始界面"""
        self.play_sound('start')
        self.add_info("欢迎来到石头剪刀布游戏！")
        self.add_info("游戏规则：")
        self.add_info("  • 石头打败剪刀")
        self.add_info("  • 剪刀打败布")
        self.add_info("  • 布打败石头")
        self.add_info("请选择你的出拳开始游戏！")
        
    def player_choose(self, choice):
        """玩家选择"""
        if self.game_in_progress:
            return
            
        self.game_in_progress = True
        self.player_choice = choice
        self.play_sound('click')
        
        # 更新玩家显示
        self.update_player_display()
        
        # 添加信息
        self.add_info(f"你选择了: {self.get_choice_name(choice)}")
        
        # 开始电脑选择动画
        self.root.after(500, self.computer_choose_animation)
        
    def computer_choose_animation(self):
        """电脑选择动画"""
        choices = ['rock', 'paper', 'scissors']
        
        def animate(frame=0):
            if frame < 10:  # 播放10帧动画
                random_choice = random.choice(choices)
                self.computer_label.config(text=self.get_choice_symbol(random_choice))
                self.root.after(100, lambda: animate(frame + 1))
            else:
                # 最终选择
                self.computer_choose()
                
        animate()
        
    def computer_choose(self):
        """电脑选择"""
        choices = ['rock', 'paper', 'scissors']
        self.computer_choice = random.choice(choices)
        
        # 更新电脑显示
        self.update_computer_display()
        
        # 添加信息
        self.add_info(f"电脑选择了: {self.get_choice_name(self.computer_choice)}")
        
        # 判断结果
        self.root.after(500, self.determine_winner)
        
    def update_player_display(self):
        """更新玩家显示"""
        symbol = self.get_choice_symbol(self.player_choice)
        self.player_label.config(text=symbol)
        
    def update_computer_display(self):
        """更新电脑显示"""
        symbol = self.get_choice_symbol(self.computer_choice)
        self.computer_label.config(text=symbol)
        
    def get_choice_symbol(self, choice):
        """获取选择符号"""
        symbols = {
            'rock': '✊',
            'paper': '✋',
            'scissors': '✌️'
        }
        return symbols.get(choice, '?')
        
    def get_choice_name(self, choice):
        """获取选择名称"""
        names = {
            'rock': '石头',
            'paper': '布',
            'scissors': '剪刀'
        }
        return names.get(choice, '未知')
        
    def determine_winner(self):
        """判断胜负"""
        if self.player_choice == self.computer_choice:
            result = "平局！"
            self.draw_count += 1
            self.play_sound('draw')
        elif (self.player_choice == 'rock' and self.computer_choice == 'scissors') or \
             (self.player_choice == 'scissors' and self.computer_choice == 'paper') or \
             (self.player_choice == 'paper' and self.computer_choice == 'rock'):
            result = "你赢了！🎉"
            self.player_score += 1
            self.play_sound('win')
        else:
            result = "电脑赢了！💻"
            self.computer_score += 1
            self.play_sound('lose')
            
        self.total_games += 1
        self.current_round += 1
        
        # 更新分数显示
        self.update_score_display()
        
        # 更新结果
        self.result_label.config(text=result)
        
        # 添加历史记录
        self.add_game_history(result)
        
        # 检查游戏是否结束
        if self.current_round >= self.max_rounds:
            self.root.after(1000, self.end_game)
        else:
            self.game_in_progress = False
            
    def update_score_display(self):
        """更新分数显示"""
        self.player_score_label.config(text=f"分数: {self.player_score}")
        self.computer_score_label.config(text=f"分数: {self.computer_score}")
        
    def add_game_history(self, result):
        """添加游戏历史"""
        history_entry = {
            'round': self.current_round,
            'player': self.player_choice,
            'computer': self.computer_choice,
            'result': result,
            'time': datetime.now().strftime("%H:%M:%S")
        }
        self.game_history.append(history_entry)
        
        # 添加信息
        self.add_info(f"第{self.current_round}轮: {result}")
        
    def add_info(self, text):
        """添加信息到文本框"""
        self.info_text.config(state='normal')
        self.info_text.insert(tk.END, f"{text}\n")
        self.info_text.see(tk.END)  # 滚动到底部
        self.info_text.config(state='disabled')
        
    def end_game(self):
        """结束游戏"""
        self.game_in_progress = False
        
        # 计算最终结果
        if self.player_score > self.computer_score:
            final_result = "恭喜你赢得了比赛！🏆"
        elif self.computer_score > self.player_score:
            final_result = "电脑赢得了比赛！"
        else:
            final_result = "比赛平局！"
            
        # 显示结果对话框
        result_text = f"比赛结束！\n\n"
        result_text += f"最终比分: {self.player_score} - {self.computer_score}\n"
        result_text += f"平局次数: {self.draw_count}\n"
        result_text += f"总游戏次数: {self.total_games}\n\n"
        result_text += final_result
        
        # 保存游戏数据
        self.save_game_data()
        
        messagebox.showinfo("比赛结果", result_text)
        
        # 重置游戏状态
        self.reset_game_state()
        
    def reset_game_state(self):
        """重置游戏状态"""
        self.current_round = 0
        self.player_score = 0
        self.computer_score = 0
        self.draw_count = 0
        self.player_choice = None
        self.computer_choice = None
        self.game_history = []
        
        # 重置显示
        self.player_label.config(text="?")
        self.computer_label.config(text="?")
        self.result_label.config(text="请选择你的出拳！")
        self.update_score_display()
        
        # 清空信息框
        self.info_text.config(state='normal')
        self.info_text.delete('1.0', tk.END)
        self.info_text.config(state='disabled')
        
        self.add_info("新游戏开始！")
        self.add_info("请选择你的出拳！")
        
    def restart_game(self):
        """重新开始游戏"""
        if self.game_in_progress:
            if not messagebox.askyesno("确认", "游戏正在进行中，确定要重新开始吗？"):
                return
                
        self.reset_game_state()
        
    def show_stats(self):
        """显示统计数据"""
        stats_win = tk.Toplevel(self.root)
        stats_win.title("游戏统计")
        stats_win.geometry("500x400")
        
        # 创建笔记本
        notebook = ttk.Notebook(stats_win)
        notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 总体统计标签页
        overall_frame = ttk.Frame(notebook)
        notebook.add(overall_frame, text="总体统计")
        
        stats = [
            ("总游戏次数:", self.total_games),
            ("玩家胜利:", self.player_score),
            ("电脑胜利:", self.computer_score),
            ("平局次数:", self.draw_count),
            ("当前连胜:", self.get_streak()),
            ("胜率:", f"{(self.player_score/self.total_games*100):.1f}%" if self.total_games > 0 else "0%")
        ]
        
        for i, (label, value) in enumerate(stats):
            tk.Label(overall_frame, text=label, font=('Microsoft YaHei', 12)).grid(
                row=i, column=0, sticky='w', padx=20, pady=10)
            tk.Label(overall_frame, text=str(value), font=('Arial', 12, 'bold')).grid(
                row=i, column=1, sticky='w', padx=20, pady=10)
                
        # 历史记录标签页
        history_frame = ttk.Frame(notebook)
        notebook.add(history_frame, text="历史记录")
        
        # 创建Treeview
        columns = ('round', 'player', 'computer', 'result', 'time')
        history_tree = ttk.Treeview(history_frame, columns=columns, show='headings', height=15)
        
        # 设置列
        history_tree.heading('round', text='轮次')
        history_tree.heading('player', text='玩家')
        history_tree.heading('computer', text='电脑')
        history_tree.heading('result', text='结果')
        history_tree.heading('time', text='时间')
        
        # 添加数据
        for entry in self.game_history[-20:]:  # 显示最近20条
            history_tree.insert('', 'end', values=(
                entry['round'],
                self.get_choice_name(entry['player']),
                self.get_choice_name(entry['computer']),
                entry['result'],
                entry['time']
            ))
            
        # 滚动条
        scrollbar = ttk.Scrollbar(history_frame, orient=tk.VERTICAL, command=history_tree.yview)
        history_tree.configure(yscrollcommand=scrollbar.set)
        
        # 布局
        history_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
    def get_streak(self):
        """获取当前连胜"""
        streak = 0
        for entry in reversed(self.game_history):
            if '赢了' in entry['result']:
                streak += 1
            else:
                break
        return streak
        
    def show_settings(self):
        """显示设置"""
        settings_win = tk.Toplevel(self.root)
        settings_win.title("游戏设置")
        settings_win.geometry("400x300")
        
        # 回合数设置
        tk.Label(settings_win, text="每局回合数:", font=('Microsoft YaHei', 12)).pack(anchor='w', padx=20, pady=(20, 5))
        
        rounds_var = tk.IntVar(value=self.max_rounds)
        rounds_spin = ttk.Spinbox(settings_win, from_=1, to=20, textvariable=rounds_var, width=10)
        rounds_spin.pack(anchor='w', padx=20, pady=(0, 20))
        
        # 音效设置
        sound_var = tk.BooleanVar(value=bool(self.sounds))
        sound_cb = ttk.Checkbutton(settings_win, text="启用音效", variable=sound_var)
        sound_cb.pack(anchor='w', padx=20, pady=(0, 20))
        
        def save_settings():
            """保存设置"""
            self.max_rounds = rounds_var.get()
            if not sound_var.get():
                self.sounds = {}  # 禁用音效
            settings_win.destroy()
            messagebox.showinfo("成功", "设置已保存")
            
        # 按钮
        btn_frame = ttk.Frame(settings_win)
        btn_frame.pack(fill=tk.X, padx=20, pady=20)
        
        ttk.Button(btn_frame, text="保存", command=save_settings).pack(side=tk.RIGHT, padx=5)
        ttk.Button(btn_frame, text="取消", command=settings_win.destroy).pack(side=tk.RIGHT, padx=5)
        
    def show_help(self):
        """显示帮助"""
        help_text = """石头剪刀布游戏 使用说明

游戏目标：
在指定回合内获得比电脑更高的分数。

游戏规则：
1. 石头打败剪刀
2. 剪刀打败布
3. 布打败石头
4. 相同则为平局

操作方法：
1. 点击三个按钮之一选择出拳
2. 电脑会随机选择出拳
3. 系统自动判断胜负
4. 先达到指定回合数的一方获胜

游戏功能：
- 动画效果显示选择过程
- 音效反馈
- 游戏统计和历史记录
- 可调整游戏设置

快捷键：
- 空格键：快速开始新游戏
- ESC键：退出游戏

祝您游戏愉快！"""
        messagebox.showinfo("游戏帮助", help_text)
        
    def load_game_data(self):
        """加载游戏数据"""
        try:
            if os.path.exists('rps_game_data.json'):
                with open('rps_game_data.json', 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    self.player_score = data.get('player_score', 0)
                    self.computer_score = data.get('computer_score', 0)
                    self.draw_count = data.get('draw_count', 0)
                    self.total_games = data.get('total_games', 0)
        except:
            pass
            
    def save_game_data(self):
        """保存游戏数据"""
        try:
            data = {
                'player_score': self.player_score,
                'computer_score': self.computer_score,
                'draw_count': self.draw_count,
                'total_games': self.total_games,
                'last_played': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
            
            with open('rps_game_data.json', 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except:
            pass
            
    def run(self):
        """运行游戏"""
        # 绑定快捷键
        self.root.bind('<space>', lambda e: self.restart_game())
        self.root.bind('<Escape>', lambda e: self.root.quit())
        self.root.bind('<F1>', lambda e: self.show_help())
        
        # 运行主循环
        self.root.mainloop()

# 主程序入口
if __name__ == "__main__":
    root = tk.Tk()
    game = RockPaperScissorsGame(root)
    game.run()