SCHOOL

                                            运行部分


此文件只适用于电脑,系统为windows7系统及以上版本,最理想版本windows11(此软件开发于windows11)加载时间1~30秒(除非性能太差或其他原因),想运行时双击击test.exe(文件名:test,扩展名写着应用程序的),启动程序在启动程序后,打开弹出的窗口,等他几秒,让他加载加载完成后,会弹出如下文字:

请输入人名(直接回车则没有):

在冒号后面输入'debug'并按下回车键(Enter)即可获得使用命令的权限


                                            命令部分


/help:显示命令帮助
请输入命令:/help
命令帮助:
命令格式1:/命令
命令格式2:/命令 参数
/exit:退出程序
/score:显示当前分数
/score set 10:设置当前分数为10
/time:显示当前时间
/time set 10:设置当前时间为10秒
/rules:显示游戏规则
/settings:打开设置窗口
/settings reset_score T/F:设置是否每次重新开始重置分数
/settings score set 10:设置当前分数为10
/settings time set 10:设置当前时间为10秒
min默认为1
max默认为7
min=1
max=7
/random:随机生成1个min~max的整数
/random 6:随机生成6个min~max的整数
/random ~ 10:随机生成随机数,范围为min到10(支持大小颠倒)
/random 10 ~:随机生成随机数,范围为10到max(支持大小颠倒)
/random ~ 10 6:随机生成6个随机数,范围为min到10(支持大小颠倒)
/random 10 ~ 6:随机生成6个随机数,范围为10到max(支持大小颠倒)
/random set ~ 10:设置随机数范围,为min到10(支持大小颠倒)
/random set 10 ~:设置随机数范围,为10到max(支持大小颠倒)
/random set 10 20:设置随机数范围,为10到20(支持大小颠倒)
/RT:启用random特效
/RT:禁用random特效
/help:显示帮助信息
您还可以来计算表达式,例如输入1+1并回车,程序会返回2


                                            程序部分


questions.json必须和test.exe放在同一个目录里!
questions.json和questions copy.json是题库,
程序默认选择加载questions.json。


                                            题库格式

{
  "riddles": [
    {
      "question": "迷",
      "answer": "答案",
      "analysis": "解析"
    },
    {
      "question": "迷",
      "answer": "答案",
      "analysis": "解析"
    }
  ],
  "xiehouyu": [
    {
      "first_part": "歇后语(前面的,如'孔夫子搬家')",
      "second_part": "答案",
      "explanation": "寓意"
    },
    {
      "first_part": "歇后语(前面的,如'孔夫子搬家')",
      "second_part": "答案",
      "explanation": "寓意"
    },
  ],
  "version": "版本"
}

                                 示例(questions.json的一部分)

{
  "riddles": [
    {
      "question": "四个'口'围小狗",
      "answer": "器",
      "analysis": "这个字谜的关键在于'口'和'犬'的组合。四个'口'字围着一个'犬'字,正好组成'器'字。"
    },
    {
      "question": "山上还有山",
      "answer": "出",
      "analysis": "这个字谜形象地描述了两个'山'字叠加在一起,形成'出'字。"
    }
  ],
  "xiehouyu": [
    {
      "first_part": "张飞审西瓜",
      "second_part": "粗中有细",
      "explanation": "猛将也有细心时"
    },
    {
      "first_part": "孔夫子搬家",
      "second_part": "净是书(输)",
      "explanation": "谐音双关"
    }
  ],
  "version": "1.0.0"
}

                                          python代码

import time
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import json
import random
from PIL import Image, ImageTk
import sys
import random

class HanziAdventure:
    def __init__(self,Name="",Name2="汉字秘境闯关",Name3="",debug=False):
        self.debug=debug
        self.window = tk.Tk()
        self.window.title(str(Name)+str(Name2)+str(Name3))
        self.window.geometry("800x600")
        self.score_default = False  # 初始化 score_default

        # 添加设置按钮,放在底部正中间
        self.settings_button = ttk.Button(self.window, text="⚙️ 设置", command=self.show_settings_window)
        self.settings_button.place(relx=0.5, rely=1.0, anchor='s', y=-10)

        # 加载题库
        with open('questions.json', 'r', encoding='utf-8') as f:
            self.questions = json.load(f)

        self.score = 0
        # 初始化默认时间为 10 分钟
        self.DEFAULT_TIME_SECOND = 600 # 10 * 60
        self.time_left = self.DEFAULT_TIME_SECOND
        self.used_questions = {
            "xiehouyu": set(),
            "riddles": set()
        }  # 记录已使用的题目索引
        self.rule_window = None  # 规则窗口
        self.version_window = None  # 版本更新窗口  # 新增
        self.current_question_type = None  # 当前题目类型
        self.current_question = None  # 当前题目


        self.commands = {}
        self.commands_open = False
        self.default_command = None

        self.exit=False
        self.window.protocol("WM_DELETE_WINDOW", self.on_window_close)  # 绑定窗口关闭事件
        
        self.random_min=1
        self.random_max=7

        self.random_effect_enabled = True

        # 创建界面
        self.create_welcome_page()


    def clear_window(self):
        """清除窗口中的所有内容"""
        if hasattr(self, 'timer_id'):  # 如果计时器存在
            self.window.after_cancel(self.timer_id)  # 停止计时器
        for widget in self.window.winfo_children():
            if widget != self.settings_button:  # 保留设置按钮
                widget.destroy()
        # 确保设置按钮始终在底部正中间
        self.settings_button.lift()  # 将按钮置于最上层
        self.settings_button.place(relx=0.5, rely=1.0, anchor='s', y=-10)


    def create_welcome_page(self):
        """创建欢迎页面"""
        self.clear_window()
        # 重置已使用的题目索引
        for key in self.used_questions:
            self.used_questions[key] = set()
        tk.Label(self.window, text="汉字秘境探险", font=("楷体", 36)).pack(pady=50)
        ttk.Button(self.window, text="开始挑战", command=self.main_game_loop).pack(pady=10)
        ttk.Button(self.window, text="挑战规则", command=self.show_rules).pack(pady=10)
        ttk.Button(self.window, text="更新谜语版本", command=self.show_version_window).pack(pady=10)  # 删除这行代码:self.settings_button.place(relx=1.0, rely=0.0, anchor='ne', x=-10, y=10)


    def load_questions(self):
        """加载题库"""
        try:
            with open(self.questions_file, 'r', encoding='utf-8') as f:
                self.questions = json.load(f)
        except Exception as e:
            messagebox.showerror("错误", f"加载题库失败: {str(e)}")
            self.questions = {"xiehouyu": [], "riddles": []}


    def show_version_window(self):
        """显示版本更新窗口"""
        if self.version_window is not None and self.version_window.winfo_exists():
            return  # 如果窗口已经存在,则不再创建

        self.version_window = tk.Toplevel(self.window)
        self.version_window.title("更新谜语版本")
        self.version_window.geometry("400x300")

        # 显示当前版本信息
        version = self.get_current_version()
        tk.Label(self.version_window, text=f"当前版本: {version}", font=("楷体", 14)).pack(pady=20)

        # 选择新题库文件
        ttk.Button(self.version_window, text="选择新题库文件", command=self.select_new_questions_file).pack(pady=10)

        # 关闭窗口时重置变量
        self.version_window.protocol("WM_DELETE_WINDOW", self.close_version_window)


    def get_current_version(self):
        """获取当前版本"""
        try:
            with open(self.questions_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                return data.get("version", "未知")
        except:
            # 如果当前打开了加载题库默认的 questions.json 文件,返回 questions.json 文件的版本号
            try:
                with open('questions.json', 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return data.get("version", "未知")
            except:
                return "未知"


    def select_new_questions_file(self):
        """选择新的题库文件"""
        file_path = tk.filedialog.askopenfilename(
            title="选择题库文件",
            filetypes=[("JSON 文件", "*.json")],
            initialdir="."
        )
        if file_path:
            if self.validate_questions_file(file_path):
                self.questions_file = file_path
                self.load_questions()
                messagebox.showinfo("成功", "题库文件已选择!")
                self.version_window.destroy()
            else:
                messagebox.showerror("错误", "选择的题库文件格式不正确")


    def validate_questions_file(self, file_path):
        """验证题库文件格式"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                if "xiehouyu" in data and "riddles" in data:
                    return True
                return False
        except:
            return False


    def close_version_window(self):
        """关闭版本更新窗口"""
        self.version_window.destroy()
        self.version_window = None


    def create_game_frame(self):
        """创建游戏主框架"""
        self.top_frame = tk.Frame(self.window)
        self.top_frame.pack(fill=tk.X)

        self.score_label = tk.Label(self.top_frame, text=f"积分: {self.score}")
        self.score_label.pack(side=tk.LEFT)

        self.timer_label = tk.Label(self.top_frame, text="剩余时间: 20:00")
        self.timer_label.pack(side=tk.RIGHT)

        self.main_frame = tk.Frame(self.window)
        self.main_frame.pack(expand=True, fill=tk.BOTH)

        # 底部按钮
        self.bottom_frame = tk.Frame(self.window)
        self.bottom_frame.pack(fill=tk.X, side=tk.BOTTOM)

        ttk.Button(self.bottom_frame, text="结束挑战", command=self.show_result).pack(side=tk.LEFT, padx=10)
        ttk.Button(self.bottom_frame, text="挑战说明", command=self.show_rules).pack(side=tk.RIGHT, padx=10)


    def update_timer(self):
        """更新计时器"""
        if not hasattr(self, 'timer_label') or not self.timer_label.winfo_exists():
            return  # 如果计时器标签不存在,直接返回

        mins, secs = divmod(self.time_left, 60)
        self.timer_label.config(text=f"剩余时间: {mins:02d}:{secs:02d}")
        if self.time_left > 0:
            self.time_left -= 1
            self.timer_id = self.window.after(1000, self.update_timer)  # 保存计时器 ID
        else:
            self.show_result()


    def show_xiehouyu(self):
        """显示歇后语题目"""
        if len(self.used_questions["xiehouyu"]) >= len(self.questions["xiehouyu"]):
            # 如果没有更多歇后语题目,检查是否还有字谜题目
            if len(self.used_questions["riddles"]) < len(self.questions["riddles"]):
                self.show_riddles()
            else:
                self.show_result()  # 所有题目都用完,直接结束游戏
            return
    
        # 确保 main_frame 存在
        if not hasattr(self, 'main_frame') or not self.main_frame.winfo_exists():
            self.create_game_frame()  # 如果 main_frame 不存在,重新创建
    
        # 随机选择一个未使用过的题目
        available_questions = [
            i for i in range(len(self.questions["xiehouyu"]))
            if i not in self.used_questions["xiehouyu"]
        ]
        question_index = random.choice(available_questions)
        self.current_question = self.questions["xiehouyu"][question_index]
        self.current_question_type = "xiehouyu"
    
        # 检查题目格式是否正确
        if 'first_part' not in self.current_question or 'second_part' not in self.current_question:
            # 记录错误日志
            with open('error_log.txt', 'a', encoding='utf-8') as f:
                f.write(f"歇后语题目格式错误,时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"题目内容: {str(self.current_question)}\n\n")
            
            # 跳过该题目
            self.used_questions["xiehouyu"].add(question_index)
            self.show_xiehouyu()
            return

        self.used_questions["xiehouyu"].add(question_index)

        question = f"{self.current_question['first_part']} —— ?"

        # 清除主框架内容
        for widget in self.main_frame.winfo_children():
            widget.destroy()

        # 显示题目
        self.question_label = tk.Label(self.main_frame, text=question, font=("楷体", 24))
        self.question_label.pack(pady=20)

        # 输入框
        self.answer_entry = ttk.Entry(self.main_frame, font=("楷体", 18))
        self.answer_entry.pack(pady=10)

        # 提交按钮
        ttk.Button(self.main_frame, text="提交答案", command=self.check_answer).pack()


    def show_riddles(self):
        """显示字谜题目"""
        if len(self.used_questions["riddles"]) >= len(self.questions["riddles"]):
            # 如果没有更多字谜题目,检查是否还有歇后语题目
            if len(self.used_questions["xiehouyu"]) < len(self.questions["xiehouyu"]):
                self.show_xiehouyu()
            else:
                self.show_result()  # 所有题目都用完,直接结束游戏
            return

        # 确保 main_frame 存在
        if not hasattr(self, 'main_frame') or not self.main_frame.winfo_exists():
            self.create_game_frame()  # 如果 main_frame 不存在,重新创建

        # 随机选择一个未使用过的题目
        available_questions = [
            i for i in range(len(self.questions["riddles"]))
            if i not in self.used_questions["riddles"]
        ]
        question_index = random.choice(available_questions)
        self.current_question = self.questions["riddles"][question_index]
        self.current_question_type = "riddles"

        # 检查题目格式是否正确
        if 'question' not in self.current_question or 'answer' not in self.current_question:
            # 记录错误日志
            with open('error_log.txt', 'a', encoding='utf-8') as f:
                f.write(f"字谜题目格式错误,时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"题目内容: {str(self.current_question)}\n\n")
            
            # 跳过该题目
            self.used_questions["riddles"].add(question_index)
            self.show_riddles()
            return

        self.used_questions["riddles"].add(question_index)

        # 动态计算答案字数
        answer_length = len(self.current_question["answer"])
        question = f"{self.current_question['question']}(答案字数: {answer_length})"

        # 清除主框架内容
        for widget in self.main_frame.winfo_children():
            widget.destroy()

        # 显示题目
        self.question_label = tk.Label(self.main_frame, text=question, font=("楷体", 24))
        self.question_label.pack(pady=20)

        # 输入框
        self.answer_entry = ttk.Entry(self.main_frame, font=("楷体", 18))
        self.answer_entry.pack(pady=10)

        # 提交按钮
        ttk.Button(self.main_frame, text="提交答案", command=self.check_answer).pack()


    def check_answer(self):
        """检查答案"""
        user_answer = self.answer_entry.get().strip()

        try:
            if self.current_question_type == "xiehouyu":
                correct_answer = self.current_question["second_part"]
            elif self.current_question_type == "riddles":
                correct_answer = self.current_question["answer"]
        except KeyError:
            with open('error_log.txt', 'a', encoding='utf-8') as f:
                f.write(f"题目格式错误,时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"题目类型: {self.current_question_type}\n")
                f.write(f"题目内容: {str(self.current_question)}\n\n")

                    
                # 更友好的提示并自动跳转到下一题
                messagebox.showwarning("提示", "当前题目数据异常,将自动跳转到下一题")
                self.main_game_loop()
                return

        if user_answer == correct_answer:
            self.score += 10
            self.score_label.config(text=f"积分: {self.score}")
            messagebox.showinfo("正确", "回答正确!")
            self.main_game_loop()  # 答对后直接更新题目
        else:
            self.show_error_buttons()  # 答错后显示按钮


    def show_error_buttons(self):
        """显示答错后的按钮"""
        # 隐藏输入框和提交按钮
        self.answer_entry.pack_forget()
        for widget in self.main_frame.winfo_children():
            if isinstance(widget, ttk.Button) and widget["text"] == "提交答案":
                widget.pack_forget()

        # 显示按钮
        ttk.Button(self.main_frame, text="重新答题", command=self.reset_question).pack(pady=5)
        ttk.Button(self.main_frame, text="展示答案", command=self.show_answer).pack(pady=5)
        ttk.Button(self.main_frame, text="下一题", command=self.main_game_loop).pack(pady=5)


    def reset_question(self):
        """重新答题"""
        # 清空输入框并重新显示输入框和提交按钮
        self.answer_entry.delete(0, tk.END)
        self.answer_entry.pack(pady=10)
        ttk.Button(self.main_frame, text="提交答案", command=self.check_answer).pack()

        # 隐藏错误按钮
        for widget in self.main_frame.winfo_children():
            if isinstance(widget, ttk.Button) and widget["text"] in ["重新答题", "展示答案", "下一题"]:
                widget.pack_forget()


    def show_answer(self):
        """展示答案"""
        # 如果答案窗口已经存在且未关闭,则直接返回
        if hasattr(self, 'answer_window') and self.answer_window.winfo_exists():
            self.answer_window.lift()  # 将窗口置于最前
            return

        # 创建自定义对话框
        self.answer_window = tk.Toplevel(self.window)
        self.answer_window.title("正确答案")
        
        # 设置答案和寓意文本
        if self.current_question_type == "xiehouyu":
            answer_text = self.current_question["second_part"]
            explanation_text = self.current_question["explanation"]
        elif self.current_question_type == "riddles":
            answer_text = self.current_question["answer"]
            explanation_text = self.current_question.get("explanation", "无解析")  # 添加解析字段,默认为"无解析"
        
        # 答案部分
        tk.Label(self.answer_window, text="答案:", font=("楷体", 14)).pack(pady=(10, 0))
        answer_box = tk.Text(self.answer_window, wrap=tk.WORD, height=1, width=20, font=("楷体", 14), bg=self.window.cget("bg"))
        answer_box.insert(tk.END, answer_text)
        answer_box.config(state=tk.DISABLED)  # 设置为只读
        answer_box.pack(padx=20, pady=5)
        
        # 含义部分
        tk.Label(self.answer_window, text="含义:", font=("楷体", 14)).pack(pady=(10, 0))
        explanation_box = tk.Text(self.answer_window, wrap=tk.WORD, height=3, width=30, font=("楷体", 14), bg=self.window.cget("bg"))
        explanation_box.insert(tk.END, explanation_text)
        explanation_box.config(state=tk.DISABLED)  # 设置为只读
        explanation_box.pack(padx=20, pady=5)
        
        # 解析部分
        tk.Label(self.answer_window, text="解析:", font=("楷体", 14)).pack(pady=(10, 0))
        analysis_box = tk.Text(self.answer_window, wrap=tk.WORD, height=5, width=40, font=("楷体", 14), bg=self.window.cget("bg"))
        analysis_text = self.current_question.get("analysis", "无解析")  # 添加解析字段,默认为"无解析"
        analysis_box.insert(tk.END, analysis_text)
        analysis_box.config(state=tk.DISABLED)  # 设置为只读
        analysis_box.pack(padx=20, pady=5)
        
        # 复制答案按钮
        def copy_answer():
            self.window.clipboard_clear()
            self.window.clipboard_append(answer_text)
            messagebox.showinfo("成功", "答案已复制到剪贴板")
        
        ttk.Button(self.answer_window, text="复制答案", command=copy_answer).pack(pady=10)
        
        # 关闭按钮
        ttk.Button(self.answer_window, text="关闭", command=self.answer_window.destroy).pack(pady=10)


    def show_rules(self):
        """显示挑战说明"""
        if self.rule_window is not None and self.rule_window.winfo_exists():
            self.rule_window.lift()  # 将窗口置于最前
            return  # 如果规则窗口已经存在,则不再创建

        self.rule_window = tk.Toplevel(self.window)
        self.rule_window.title("挑战说明")
        self.rule_window.geometry("500x300")

        rules_text = """
        游戏规则:
        1. 每次回答一个题目,题目类型包括歇后语、字谜。
        2. 答对一题得10分。
        3. 答错后可以选择重新答题、查看答案或跳过。
        4. 时间结束后或主动结束挑战时显示最终得分。
        """
        #去除空格
        rules_text = rules_text.replace(" ", "")
        tk.Label(self.rule_window, text=rules_text, font=("楷体", 14), justify=tk.LEFT).pack(pady=20)

        # 关闭规则窗口时重置变量
        self.rule_window.protocol("WM_DELETE_WINDOW", self.close_rule_window)


    def close_rule_window(self):
        """关闭规则窗口"""
        self.rule_window.destroy()
        self.rule_window = None


    def show_result(self):
        """显示最终结果"""
        self.clear_window()  # 清除所有窗口内容
        # 重置分数和时间
        if self.score_default:
            self.score = 0
        self.time_left = self.DEFAULT_TIME_SECOND
    
        tk.Label(self.window, text="挑战结束!", font=("楷体", 36)).pack(pady=50)
        tk.Label(self.window, text=f"你的最终得分是: {self.score}", font=("楷体", 24)).pack()
        ttk.Button(self.window, text="重新开始", command=self.create_welcome_page).pack()


    def main_game_loop(self):
        """主游戏逻辑"""
        self.clear_window()  # 清除当前窗口内容,包括结束页
        self.create_game_frame()
        self.update_timer()
        # 确保设置按钮始终可见
        self.settings_button.lift()
        self.settings_button.place(relx=0.5, rely=1.0, anchor='s', y=-10)

    
        # 随机选择一种题目类型
        question_types = ["xiehouyu", "riddles"]
        self.current_question_type = random.choice(question_types)
        if self.current_question_type == "xiehouyu":
            self.show_xiehouyu()
        elif self.current_question_type == "riddles":
            self.show_riddles()


    def run(self):
        """运行程序"""
        self.window.mainloop()


    def show_settings_window(self):
        """显示设置窗口"""
        # 如果设置窗口已经存在且未关闭,则直接返回
        if hasattr(self, 'settings_window') and self.settings_window.winfo_exists():
            self.settings_window.lift()  # 将窗口置于最前
            return

        self.settings_window = tk.Toplevel(self.window)
        self.settings_window.title("设置")
        self.settings_window.geometry("300x220")

        # 添加分数重置选项
        tk.Label(self.settings_window, text="分数设置", font=("楷体", 14)).pack(pady=5)
        self.score_default_var = tk.BooleanVar(value=self.score_default)
        ttk.Checkbutton(self.settings_window, text="每次重新开始重置分数", 
                       variable=self.score_default_var).pack()

        # 添加当前分数设置
        tk.Label(self.settings_window, text="当前分数", font=("楷体", 14)).pack(pady=5)
        self.score_entry = ttk.Entry(self.settings_window)
        self.score_entry.insert(0, str(self.score))
        self.score_entry.pack()

        # 添加时间设置
        tk.Label(self.settings_window, text="默认时间(秒)", font=("楷体", 14)).pack(pady=5)
        self.time_entry = ttk.Entry(self.settings_window)
        self.time_entry.insert(0, str(self.DEFAULT_TIME_SECOND))
        self.time_entry.pack()

        # 保存按钮
        ttk.Button(self.settings_window, text="保存", command=self.save_settings).pack(pady=10)

        # 关闭窗口时重置变量
        self.settings_window.protocol("WM_DELETE_WINDOW", self.close_settings_window)


    def close_settings_window(self):
        """关闭设置窗口"""
        self.settings_window.destroy()
        del self.settings_window


    def save_settings(self):
        """保存设置"""
        try:
            # 更新分数重置选项
            self.score_default = self.score_default_var.get()

            # 更新当前分数
            new_score = int(self.score_entry.get())
            self.score = new_score
            if hasattr(self, 'score_label'):
                self.score_label.config(text=f"积分: {self.score}")

            # 更新默认时间
            new_time = int(self.time_entry.get())
            self.DEFAULT_TIME_SECOND = new_time
            self.time_left = new_time
            if hasattr(self, 'timer_label'):
                mins, secs = divmod(self.time_left, 60)
                self.timer_label.config(text=f"剩余时间: {mins:02d}:{secs:02d}")

            messagebox.showinfo("成功", "设置已保存!")
            self.settings_window.destroy()
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字")


    def change_variable(self, var_name, new_value, value_type=None):
        if not hasattr(self, var_name):
            return None

        if value_type is not None and not isinstance(new_value, value_type):
            return None

        setattr(self, var_name, new_value)
        return True


    def show_settings_window(self):
        """显示设置窗口"""
        # 如果设置窗口已经存在且未关闭,则直接返回
        if hasattr(self, 'settings_window') and self.settings_window.winfo_exists():
            return

        self.settings_window = tk.Toplevel(self.window)
        self.settings_window.title("设置")
        self.settings_window.geometry("300x220")

        # 添加分数重置选项
        tk.Label(self.settings_window, text="分数设置", font=("楷体", 14)).pack(pady=5)
        self.score_default_var = tk.BooleanVar(value=self.score_default)
        ttk.Checkbutton(self.settings_window, text="每次重新开始重置分数", 
                       variable=self.score_default_var).pack()

        # 添加当前分数设置
        tk.Label(self.settings_window, text="当前分数", font=("楷体", 14)).pack(pady=5)
        self.score_entry = ttk.Entry(self.settings_window)
        self.score_entry.insert(0, str(self.score))
        self.score_entry.pack()

        # 添加时间设置
        tk.Label(self.settings_window, text="默认时间(秒)", font=("楷体", 14)).pack(pady=5)
        self.time_entry = ttk.Entry(self.settings_window)
        self.time_entry.insert(0, str(self.DEFAULT_TIME_SECOND))
        self.time_entry.pack()

        # 保存按钮
        ttk.Button(self.settings_window, text="保存", command=self.save_settings).pack(pady=10)

        # 关闭窗口时重置变量
        self.settings_window.protocol("WM_DELETE_WINDOW", self.close_settings_window)


    def save_settings(self):
        """保存设置"""
        try:
            # 更新分数重置选项
            self.score_default = self.score_default_var.get()

            # 更新当前分数
            new_score = int(self.score_entry.get())
            self.score = new_score
            if hasattr(self, 'score_label'):
                self.score_label.config(text=f"积分: {self.score}")

            # 更新默认时间
            new_time = int(self.time_entry.get())
            self.DEFAULT_TIME_SECOND = new_time
            self.time_left = new_time
            if hasattr(self, 'timer_label'):
                mins, secs = divmod(self.time_left, 60)
                self.timer_label.config(text=f"剩余时间: {mins:02d}:{secs:02d}")

            messagebox.showinfo("成功", "设置已保存!")
            self.settings_window.destroy()
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字")


    def command(self):
        print("/help:显示命令帮助")
        while not self.exit:
            try:
                command = input("请输入命令:")
            except:
                sys.exit()       
            self.compile_command(command)


    def command_exit(self):
        try:
            if not self.window.winfo_exists():
                self.exit = True
                if self.debug:
                    print("/exit")
                print(f"Gui程序已退出")
                print(f"分数:{self.score}")
                print(f"时间:{self.time_left}")

                print("\r",end="")
                sys.exit()
        except:
            self.exit = True
            if self.debug:
                print("/exit")
            print(f"Gui程序已退出")
            print(f"分数:{self.score}")
            print(f"时间:{self.time_left}")
            print("\r",end="")
            sys.exit()


    def on_window_close(self):
        """窗口关闭时触发"""
        self.window.destroy()  # 关闭窗口
        self.command_exit()  # 调用 command_exit 函数


    def eval_expression(self, expr):
        """
        计算字符串表达式
        :param expr: 字符串表达式
        :return: 计算结果,如果表达式无效则返回None
        """
        try:
            # 只允许数字和基本运算符
            allowed_chars = set('0123456789+-*/%^(). ')
            if not all(char in allowed_chars for char in expr):
                return None
            
            # 将 ^ 替换为 **
            expr = expr.replace('^', '**')
            
            # 使用eval计算表达式
            return eval(expr)
        except:
            return None
        

    def compile_command(self, command=""):
        # 检查命令是否为空
        if command:
            if command[0] == "/":
                # 执行命令
                command = command[1:]

                if command == "exit":
                    self.window.destroy()
                    self.exit = True
                    print(f"程序已退出")
                    print(f"分数:{self.score}")
                    print(f"时间:{self.time_left}")
                    sys.exit()

                if command == "RT":
                    self.random_effect_enabled = True
                    print("已开启random特效")
                    return
                elif command == "RF":
                    self.random_effect_enabled = False
                    print("已关闭random特效")
                    return

                if command.startswith("score"):
                    """
                    /score:显示当前分数
                    /score set 10:设置当前分数为10
                    """
                    parts = command.split()
                    if len(parts) == 1:
                        print(f"当前分数:{self.score}")
                    elif len(parts) == 3 and parts[1] == "set" and parts[2].isdigit():
                        self.score = int(parts[2])
                        print(f"当前分数:{self.score}")
                    else:
                        print(f"score命令无效")

                elif command.startswith("time"):
                    """
                    /time:显示当前时间
                    /time set 10:设置当前时间为10秒
                    """
                    parts = command.split()
                    if len(parts) == 1:
                        print(f"当前时间:{self.time_left}")
                    elif len(parts) == 3 and parts[1] == "set":
                        try:
                            new_time = int(parts[2])
                            self.time_left = new_time
                            self.DEFAULT_TIME_SECOND = new_time  # 同时更新默认时间
                            print(f"当前时间已设置为: {self.time_left}秒")
                        except ValueError:
                            print(f"请输入有效的时间")
                    else:
                        print(f"time命令无效")

                elif command == "rules":
                    self.show_rules()


                elif command == "settings":
                    self.show_settings_window()
                    return


                elif command.startswith("settings"):
                    parts = command.split()
                    if len(parts) == 3 and parts[1] == "reset_score":
                        if parts[2].upper() == "T":
                            self.score_default = True
                            print(f"已设置为每次重新开始重置分数")
                        elif parts[2].upper() == "F":
                            self.score_default = False
                            print(f"已设置为每次重新开始保存分数")
                        else:
                            print(f"settings命令无效")
                    elif len(parts) == 4 and parts[1] == "score" and parts[2] == "set":
                        try:
                            new_score = int(parts[3])
                            self.score = new_score
                            print(f"当前分数已设置为: {self.score}")
                        except ValueError:
                            print(f"请输入有效的分数")
                    elif len(parts) == 4 and parts[1] == "time" and parts[2] == "set":
                        try:
                            new_time = int(parts[3])
                            self.DEFAULT_TIME_SECOND = new_time
                            self.time_left = new_time
                            print(f"当前时间已设置为: {self.time_left}秒")
                        except ValueError:
                            print(f"请输入有效的时间")
                    else:
                        print(f"settings命令无效")

                elif command.startswith("random"):
                    print(f"随机数生成器(min:{self.random_min},max:{self.random_max})")
                    try:
                        parts = command.split()
                        
                        def get_range(a, b):
                            return (min(a, b), max(a, b))
                        
                        def show_random_effect(min_val, max_val):
                            LongStr=len(str(max_val))
                            # 添加类似 a.py 的动态效果
                            for i in range(50):
                                print("\r" + str(random.randint(min_val, max_val)) + LongStr*" ", end="")
                                time.sleep(0.05)
                            print("\r", end="\r")
                        
                        if len(parts) == 1:
                            # /random: 生成1个随机数
                            if self.random_effect_enabled:
                                show_random_effect(self.random_min, self.random_max)
                            num = random.randint(self.random_min, self.random_max)
                            print(num)
                        elif len(parts) == 2 and parts[1].isdigit():
                            # /random 6: 生成6个随机数
                            count = int(parts[1])
                            if self.random_effect_enabled:
                                show_random_effect(self.random_min, self.random_max)
                            nums = [random.randint(self.random_min, self.random_max) for _ in range(count)]
                            print(nums)
                        elif len(parts) == 3 and parts[1] == "~":
                            # /random ~ 10: 生成1个随机数,范围为min到10
                            new_max = int(parts[2])
                            min_val, max_val = get_range(self.random_min, new_max)
                            if self.random_effect_enabled:
                                show_random_effect(min_val, max_val)
                            print(random.randint(min_val, max_val))
                        elif len(parts) == 3 and parts[2] == "~":
                            # /random 10 ~: 生成1个随机数,范围为10到max
                            new_min = int(parts[1])
                            min_val, max_val = get_range(new_min, self.random_max)
                            if self.random_effect_enabled:
                                show_random_effect(min_val, max_val)
                            print(random.randint(min_val, max_val))
                        elif len(parts) == 4 and parts[1] == "~":
                            # /random ~ 10 6: 生成6个随机数,范围为min到10
                            new_max = int(parts[2])
                            count = int(parts[3])
                            min_val, max_val = get_range(self.random_min, new_max)
                            if self.random_effect_enabled:
                                show_random_effect(min_val, max_val)
                            print([random.randint(min_val, max_val) for _ in range(count)])
                        elif len(parts) == 4 and parts[2] == "~" and "set" not in parts:
                            # /random 10 ~ 6: 生成6个随机数,范围为10到max
                            new_min = int(parts[1])
                            count = int(parts[3])
                            min_val, max_val = get_range(new_min, self.random_max)
                            if self.random_effect_enabled:
                                show_random_effect(min_val, max_val)
                            print([random.randint(min_val, max_val) for _ in range(count)])
                        elif len(parts) == 4 and parts[1] == "set":
                            if parts[2] == "~" and parts[3] == "~":
                                # /random set ~ ~: 设置随机数范围为min到max
                                self.random_min, self.random_max = get_range(self.random_min, self.random_max)
                                print(f"随机数范围已设置为: {self.random_min} ~ {self.random_max}(没变)")
                            elif parts[2] == "~":
                                # /random set ~ 10: 设置随机数范围为min到10
                                new_max = int(parts[3])
                                self.random_min, self.random_max = get_range(self.random_min, new_max)
                                print(f"随机数范围已设置为: {self.random_min} ~ {self.random_max}")
                            elif parts[3] == "~":
                                # /random set 10 ~: 设置随机数范围为10到max
                                new_min = int(parts[2])
                                self.random_min, self.random_max = get_range(new_min, self.random_max)
                                print(f"随机数范围已设置为: {self.random_min} ~ {self.random_max}")
                            else:
                                # /random set 10 20: 设置随机数范围为10到20
                                new_min = int(parts[2])
                                new_max = int(parts[3])
                                self.random_min, self.random_max = get_range(new_min, new_max)
                                print(f"随机数范围已设置为: {self.random_min} ~ {self.random_max}")
                        else:
                            print("random命令无效")
                    except Exception as e:
                        print(f"发生错误!\n{e}")

                elif command == "help":
                    COMMAND_HELP = """命令帮助:
                    命令格式1:/命令
                    命令格式2:/命令 参数
                    /exit:退出程序
                    /score:显示当前分数
                    /score set 10:设置当前分数为10
                    /time:显示当前时间
                    /time set 10:设置当前时间为10秒
                    /rules:显示游戏规则
                    /settings:打开设置窗口
                    /settings reset_score T/F:设置是否每次重新开始重置分数
                    /settings score set 10:设置当前分数为10
                    /settings time set 10:设置当前时间为10秒
                    min默认为1
                    max默认为7
                    min=1
                    max=7
                    /random:随机生成1个min~max的整数
                    /random 6:随机生成6个min~max的整数
                    /random ~ 10:随机生成随机数,范围为min到10(支持大小颠倒)
                    /random 10 ~:随机生成随机数,范围为10到max(支持大小颠倒)
                    /random ~ 10 6:随机生成6个随机数,范围为min到10(支持大小颠倒)
                    /random 10 ~ 6:随机生成6个随机数,范围为10到max(支持大小颠倒)
                    /random set ~ 10:设置随机数范围,为min到10(支持大小颠倒)
                    /random set 10 ~:设置随机数范围,为10到max(支持大小颠倒)
                    /random set 10 20:设置随机数范围,为10到20(支持大小颠倒)
                    /help:显示帮助信息
                    您还可以来计算表达式,例如输入1+1并回车,程序会返回2
                    """.replace("                    ", "")
                    print(COMMAND_HELP,end="")

                else:
                    print(f"有\"/\"命令无效")
            else:
                Num=self.eval_expression(command)
                if Num!=None:
                    try:
                        print(f"{Num}")
                    except:
                        print(f"表达式命令无效")
                else:
                    print(f"无\"/\"命令无效")
#主程序
if __name__ == "__main__":
    Name=input("请输入人名(直接回车则没有):")
    if Name=="":
        app = HanziAdventure(Name="",debug=False)
        app.run()
    elif Name=="debug":
        app = HanziAdventure(Name="调试模式--",debug=True)
        print("已进入调试模式")
        app.command()
    else:  
        app = HanziAdventure(Name=Name+"----",debug=False)
        app.run()

                             json文件(questions.json)

{
  "riddles": [
    {
      "question": "四个'口'围小狗",
      "answer": "器",
      "analysis": "这个字谜的关键在于'口'和'犬'的组合。四个'口'字围着一个'犬'字,正好组成'器'字。"
    },
    {
      "question": "山上还有山",
      "answer": "出",
      "analysis": "这个字谜形象地描述了两个'山'字叠加在一起,形成'出'字。"
    },
    {
      "question": "一加一不是二",
      "answer": "王",
      "analysis": "这个字谜需要从字形上理解。'一'加'一',再加上一个'丨',就组成了'王'字。"
    },
    {
      "question": "九十九",
      "answer": "白",
      "analysis": "这个字谜需要数学思维。'百'字去掉'一',就是'白'字。"
    },
    {
      "question": "夫人回娘家",
      "answer": "圭",
      "analysis": "这个字谜中,'夫'字中的'女'字回到'家'中,就形成了'圭'字。"
    }
  ],
  "xiehouyu": [
    {
      "first_part": "张飞审西瓜",
      "second_part": "粗中有细",
      "explanation": "猛将也有细心时"
    },
    {
      "first_part": "孔夫子搬家",
      "second_part": "净是书(输)",
      "explanation": "谐音双关"
    },
    {
      "first_part": "外甥打灯笼",
      "second_part": "照舅(旧)",
      "explanation": "谐音双关"
    },
    {
      "first_part": "和尚打伞",
      "second_part": "无法无天",
      "explanation": "双关语"
    },
    {
      "first_part": "泥菩萨过河",
      "second_part": "自身难保",
      "explanation": "比喻自身难保"
    },
    {
      "first_part": "狗拿耗子",
      "second_part": "多管闲事",
      "explanation": "比喻多管闲事"
    },
    {
      "first_part": "猪八戒照镜子",
      "second_part": "里外不是人",
      "explanation": "比喻两面不讨好"
    },
    {
      "first_part": "老虎屁股",
      "second_part": "摸不得",
      "explanation": "比喻不能招惹"
    },
    {
      "first_part": "老鼠过街",
      "second_part": "人人喊打",
      "explanation": "比喻人人痛恨"
    },
    {
      "first_part": "竹篮打水",
      "second_part": "一场空",
      "explanation": "比喻白费力气"
    },
    {
      "first_part": "瞎子点灯",
      "second_part": "白费蜡",
      "explanation": "比喻白费力气"
    },
    {
      "first_part": "黄鼠狼给鸡拜年",
      "second_part": "没安好心",
      "explanation": "比喻不怀好意"
    },
    {
      "first_part": "哑巴吃黄连",
      "second_part": "有苦说不出",
      "explanation": "比喻有苦难言"
    },
    {
      "first_part": "骑驴看唱本",
      "second_part": "走着瞧",
      "explanation": "比喻看事情发展"
    },
    {
      "first_part": "铁公鸡",
      "second_part": "一毛不拔",
      "explanation": "比喻非常吝啬"
    },
    {
      "first_part": "鸡蛋碰石头",
      "second_part": "不自量力",
      "explanation": "比喻自不量力"
    },
    {
      "first_part": "猫哭老鼠",
      "second_part": "假慈悲",
      "explanation": "比喻假慈悲"
    },
    {
      "first_part": "猴子捞月亮",
      "second_part": "白忙一场",
      "explanation": "比喻白费力气"
    },
    {
      "first_part": "画蛇添足",
      "second_part": "多此一举",
      "explanation": "比喻多余的行为"
    },
    {
      "first_part": "对牛弹琴",
      "second_part": "白费劲",
      "explanation": "比喻对不懂的人说教"
    }
  ],
  "version": "1.0.0"
}

                        json文件(questions copy.json)

{
  "riddles": [
    {
      "question": "刘邦闻之喜,刘备闻之悲",
      "answer": "翠",
      "analysis": "将 ' 羽' 和 ' 卒' 组合,项羽死亡刘邦会高兴,关羽死亡刘备会悲伤,通过历史人物的命运和情感构建字谜,寓意着文字可巧妙关联复杂的历史情境与人物情感"
    },
    {
      "question": "一字十八口,果木它为首",
      "answer": "杏",
      "analysis": "把 ' 十'、' 八 '、' 口 ' 组合成 ' 杏' 字,且 ' 杏' 属于木字旁果木,从字形结构和属性分类两个角度设计谜面,寓意着汉字构造与事物分类的紧密联系"
    },
    {
      "question": "三横穿两竖,帝王藏深处",
      "answer": "州",
      "analysis": "三横两竖构成 ' 州' 字,古九州象征帝王统治疆域,借助历史文化概念与字形的对应关系创作,寓意着汉字与古代政治地理概念的依存"
    },
    {
      "question": "头戴四方帽,身背半边刀",
      "answer": "罰(罚)",
      "analysis": "将 ' 罒' 比作四方帽,' 刂 ' 与' 言 ' 组合成 ' 罚',利用形象比喻和字形组合设谜,寓意汉字可通过形象化部件构建复杂表意"
    },
    {
      "question": "孔明借东风,周瑜用火攻",
      "answer": "燥",
      "analysis": "赤壁之战中周瑜用火攻,火攻需要干燥环境,由此关联到 ' 燥' 字,结合历史典故与生活常识设计,寓意汉字能关联历史事件与现实情境"
    },
    {
      "question": "一字九横六直,颜回问孔子",
      "answer": "晶",
      "analysis": "把 ' 日' 字重复三次得到 ' 晶' 字,共九横六直,以字形特征和文化典故结合,寓意汉字构造规律与文化传承的关联"
    },
    {
      "question": "上不在上,下不在下,人有它大,天没它大",
      "answer": "一",
      "analysis": "从哲学层面强调 ' 一' 的特殊地位,' 上 ' 字去掉上面部分是 ' 一',' 下 ' 字去掉下面部分是 ' 一',' 人 ' 加' 一 ' 是' 大 ',' 天 ' 去掉 ' 一' 是 ' 大',寓意汉字可蕴含抽象哲学概念"
    },
    {
      "question": "道士腰挂两铃,和尚脚踏一云",
      "answer": "平",
      "analysis": "把 ' 平' 字中的两点想象成道士腰挂的两铃,下面部分看作 ' 干' 的变形即和尚脚踏的一云,利用形象化联想和字形拆解,寓意汉字部件可通过创意联想构建有趣谜面"
    },
    {
      "question": "一字四十八头,老农用它盖楼",
      "answer": "井",
      "analysis": "将 ' 井' 字拆解为四个 ' 十' 和八个 ' 一',同时结合生活中井与盖楼(打水等用途)的联系,预期单词谜题字形拆解与生活场景的融合"
    },
    {
      "question": "大雨冲倒山,风卷残云散",
      "answer": "岁",
      "analysis": "把 ' 山' 字倒下变为 ' 彐',' 云 ' 字被风卷散剩余 ' 夕',二者组合成 ' 岁',利用字形动态变化设谜,预期单词谜题可通过形象化的变化传达信息"
    },
    {
      "question": "左看可耕田,右看可攻战",
      "answer": "矛",
      "analysis": "把 ' 矛' 字左边看作 ' 耒'(农具象征耕田),右边看作兵器象征攻战,从字形部件的象征功能出发,预期单词谜题能反映古代生产生活与军事活动"
    },
    {
      "question": "孔圣删诗书,一字定春秋",
      "answer": "删",
      "analysis": "孔子删《诗经》,' 删 ' 字包含 ' 册'(代表书籍)和 ' 刂'(刀,象征删减动作),依据历史文化事件和字形部件表意创作,预期单词谜题与文化传承中的编辑整理行为相关"
    },
    {
      "question": "木字多一撇,莫作禾字猜",
      "answer": "移",
      "analysis": "把 ' 多' 和 ' 一撇 ' 组合成 ' 移' 字,避免误解为 ' 禾',利用字形相似性和组合变化,预期单词谜题组合的多样性与易错性"
    },
    {
      "question": "李白诗成泣鬼神,杜甫笔下惊风雨",
      "answer": "骚",
      "analysis": "屈原《离骚》为诗宗,通过李白、杜甫诗歌成就暗示古代诗歌源头,又因屈原投江与马有关(一种说法)暗指 ' 马',从而关联到 ' 骚' 字,预期单词谜题可关联丰富文学脉络和历史典故"
    },
    {
      "question": "三个老鼠顶本书",
      "answer": "鼐",
      "analysis": "把 ' 鼐' 看作 ' 鼎' 的古字,将三个 ' 鼠' 谐音为 ' 三足 ',从字形形象与谐音角度创作,预期单词谜题的演变与形象化谐音的巧妙运用"
    },
    {
      "question": "项羽自刎乌江,刘邦大笑三声",
      "answer": "翠",
      "analysis": "再次以项羽死亡刘邦高兴,关羽死亡刘备悲伤的典故,强化对 ' 翠' 字与历史事件联系的理解,预期单词谜题可反复承载重要历史文化信息"
    },
    {
      "question": "始皇焚书坑儒,唯留一字不毁",
      "answer": "政",
      "analysis": "秦朝以 ' 政' 为核心制度,且秦始皇名 ' 政',从政治制度和人物名字双重角度关联到 ' 政' 字,预期单词谜题与古代政治统治和人物标识的紧密联系"
    },
    {
      "question": "诸葛布八卦,陆逊困阵中",
      "answer": "图",
      "analysis": "把八卦形象用 ' 口' 表示,陆逊字伯言,' 阵 ' 中困 ' 冬'(以部分代整体)组合成 ' 图' 字,结合历史典故与字形拆解,预期单词谜题与历史军事文化和字形组合创意的融合"
    },
    {
      "question": "武则天造字,日月当空照",
      "answer": "曌",
      "analysis": "武则天自创 ' 曌' 字表示日月凌空,展示汉字的创新性和特定历史时期的文化现象,预期单词谜题可因特殊历史人物和需求而创造新形式"
    },
    {
      "question": "东坡画竹,板桥写兰",
      "answer": "筠",
      "analysis": "苏轼(东坡)善画竹,郑板桥善写兰,将 ' 竹' 与 ' 均' 组合成 ' 筠' 字,依据文人特长与汉字组合,预期单词谜题与文人文化的关联"
    },
    {
      "question": "一字生得奇,上下都是八,中间十字架",
      "answer": "米",
      "analysis": "把 ' 米' 字拆解为上下两个 ' 八',中间一个 ' 十' 字,从字形结构出发,预期单词谜题独特的结构美感和形象化表意"
    },
    {
      "question": "一横又一直,猜十字不对",
      "answer": "支",
      "analysis": "将 ' 十' 和 ' 又' 组合成 ' 支' 字,利用笔画组合的误导性,预期单词谜题组合的灵活性和易混淆性"
    },
    {
      "question": "三山倒挂,二月相连",
      "answer": "用",
      "analysis": "把 ' 用' 字上半部分看作三山倒写,下半部分看作两月相连,从字形形象组合设谜,预期单词谜题可通过形象化联想构建字形"
    },
    {
      "question": "四个晚上,猜一字",
      "answer": "罗",
      "analysis": "将 ' 夕'(代表晚上)重复四次组合成 ' 羅'(简体 ' 罗'),从字形重复组合角度创作,预期单词谜题组合方式的多样性"
    },
    {
      "question": "孔子登山,孟子望海",
      "answer": "岳",
      "analysis": "把 ' 丘'(孔子名丘)和 ' 山' 组合成 ' 岳' 字,利用孟子望海作干扰,突出主要关联,预期单词谜题可与历史人物名字和地理元素结合"
    },
    {
      "question": "一字十一笔,无横又无直",
      "answer": "淡",
      "analysis": "通过笔画拆分技巧,' 淡 ' 字有十一笔且无横画和竖画,体现汉字笔画构成的独特性,预期单词谜题笔画组合的特殊规律"
    },
    {
      "question": "曹操割发,关羽弃袍",
      "answer": "形",
      "analysis": "曹操割发对应 ' 彡',关羽弃袍对应 ' 开',组合成 ' 形' 字,结合历史人物行为与字形部件,预期单词谜题可通过历史故事进行创意拆解组合"
    },
    {
      "question": "颜回问子路,孔子在何处",
      "answer": "哈",
      "analysis": "孔子字仲尼,' 口 ' 含' 合 ' 组成 ' 哈' 字,从文化典故和字形组合角度,预期单词谜题与文化人物字号的关联"
    },
    {
      "question": "一字四十八点,秀才问遍天下",
      "answer": "井",
      "analysis": "同前面 ' 井' 字拆解,从另一种角度描述 ' 井' 字笔画(将笔画看作点的组合),强化对 ' 井' 字的理解,预期单词谜题可从多种角度进行解读和描述"
    },
    {
      "question": "韩信点兵,多多益善",
      "answer": "帅",
      "analysis": "把 ' 师' 去掉一横得到 ' 帅',结合韩信作为统帅点兵典故,预期单词谜题可通过字形变化关联历史军事概念"
    }
  ],
  "xiehouyu": [],
  "version": "2.2.1"
}
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值