import random class Puzzle: pass class BlankPuzzle(Puzzle): """填空题谜题生成器 Args: text: 原始字符串(需要 "/" 分割句子, 末尾应有 "/") min_denominator: 最小概率倒数(如占所有可生成填空数的 1/7 中的 7, 若期望值小于 1, 则取 1) """ def __init__(self, text: str, min_denominator: int): 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]) self.answer = answer self.wording = "".join(blanked_words) 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: dict, jammer: list, max_riddles_num: int = 2, prefix: str = "" ): self.prefix = prefix self.mapping = mapping self.jammer = list(set(jammer + list(mapping.values()))) while len(self.jammer) < 4: self.jammer.append(" ") self.max_riddles_num = max(1, min(max_riddles_num, 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: 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 in enumerate(puzzles): 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)}" if __name__ == "__main__": 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)