import random class Puzzle(): pass class BlankPuzzle(Puzzle): """填空题谜题生成器 Args: text: 原始字符串(需要 "/" 分割句子, 末尾应有 "/") min_denominator: 最小概率倒数(如占所有可生成填空数的 1/7 中的 7, 若期望值小于 1, 则取 1) """ def __init__(self, text, min_denominator): self.text = text self.min_denominator = min_denominator self.wording = "填空题 - 尚未刷新谜题" self.answer = ["填空题 - 尚未刷新谜题"] def refresh(self): # 刷新谜题 placeholder = "___SLASH___" tmp_text = self.text.replace("/", placeholder) words = tmp_text.split(placeholder) if not words: return "" words = [word for word in words if word] num_blanks = min(max(1, len(words) // self.min_denominator), len(words)) indices_to_blank = random.sample(range(len(words)), num_blanks) indices_to_blank.sort() blanked_words = list(words) answer = list() for index in indices_to_blank: blanked_words[index] = "__" * len(words[index]) answer.append(words[index]) result = [] for word in blanked_words: result.append(word) self.answer = answer self.wording = "".join(result) def __str__(self): return f"{self.wording}\n{str(self.answer)}" class SelectionPuzzle(Puzzle): """选择题谜题生成器 Args: mapping: 正确选项映射 {问题: 答案} jammer: 干扰项列表 max_riddles_num: 最大生成谜题数 (默认2个) prefix: 问题前缀 """ def __init__(self, mapping, jammer: list, max_riddles_num: int = 2, prefix: str = ""): jammer += ["1","2","3","4"] self.prefix = prefix self.mapping = mapping self.jammer = list(set(jammer + list(mapping.values()))) # 合并干扰项和正确答案并去重 self.max_riddles_num = max(1, min(max_riddles_num, 5)) # 限制1-5个谜题 self.wording = "选择题 - 尚未刷新谜题" self.answer = ["选择题 - 尚未刷新谜题"] self.options = [] def refresh(self): """刷新谜题,根据题目数量生成适当数量的谜题""" if not self.mapping: self.wording = "无可用题目" self.answer = ["无答案"] self.options = [] return # 确定实际生成的谜题数量 num_questions = min(self.max_riddles_num, len(self.mapping)) questions = random.sample(list(self.mapping.items()), num_questions) # 生成谜题 puzzles = [] answers = [] all_options = [] for question, correct_answer in questions: # 生成选项 (正确答案 + 3个干扰项) options = [correct_answer] available_jammers = [j for j in self.jammer if j != correct_answer] if len(available_jammers) >= 3: selected_jammers = random.sample(available_jammers, 3) else: selected_jammers = random.choices(available_jammers, k=3) options.extend(selected_jammers) random.shuffle(options) puzzles.append(question) answers.append(correct_answer) all_options.append(options) question_texts = [] for i, (puzzle, options) in enumerate(zip(puzzles, all_options)): #options_text = "\n".join([f" {chr(97+j)}. {opt}" for j, opt in enumerate(options)]) question_texts.append(f"{self.prefix}:\n {i+1}. {puzzle}") self.wording = question_texts self.answer = answers self.options = all_options def __str__(self): return f"{self.wording}\n正确答案: {', '.join(self.answer)}" puz = SelectionPuzzle({"1+1":"2", "1+2":"3", "1+3": "4"}, ["2","5","0"], 3, '求值: ') puz.refresh() print(puz.wording) print(puz.answer) print(puz.options)