解决问答游戏题库重复抽取问题:移除已选字典元素的方法
解决问答游戏重复抽取问题的方案
问题说明
我开发了一个小型问答游戏,通过代码生成两个文本文件分别存储问题字典和答案字典,后续从文件读取字典随机抽取10道题,记录玩家答案并计分,但目前存在同一问题被多次抽取的情况,需要实现抽取后移除问题字典中对应项的方法。
原游戏运行代码
import ast import random with open("question.txt", "r") as questions: qdic = ast.literal_eval(questions.read()) with open("answers.txt", "r") as answers: adic = ast.literal_eval(answers.read()) print("Welcome to my quiz!") answer = input("Are you ready to play the quiz? (yes/no) :") name = input(f"\nWhat's your name? ") points = 0 total_questions = 10 while total_questions <= 10: if answer.lower() == "yes": question = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] for i in range(len(question)): answers = input(f"Question " + str(question[i]) + ": " + random.choice(list(qdic.values()))) givenAnswer = answers if givenAnswer.lower() in adic.values(): points += 1 print("Correct!") else: print("Wrong answer =(") i += 1 total_questions += 1
问题与答案字典生成代码
import json questions = {"1": "What year did man land on the moon?", "2": "Which Indonesian island shares a name with a programming language? ", "3": "What is the formula for water? ", "4": "The UV in UV rays stand for what? ", "5": "Which currency was used in italy prior to the Euro? ", "6": "Where was the croissant invented? ", "7": "Which movie won the first Oscar for best picture? ", "8": "What musical piece was Mozart's last? ", "9": "What country was Stalin born? ", "10": "Who separated the red sea in the old testament? "} with open("question.txt", "w") as question_file: question_file.write(json.dumps(questions)) answers = {"1": "1969", "2": "java", "3": "h20", "4": "ultraviolet", "5": "lira", "6": "austria", "7": "wings", "8": "requiem", "9": "georgia", "10": "moses" } with open("answers.txt", "w") as answers_file: answers_file.write(json.dumps(answers))
解决方案
核心是抽取问题后同步删除问题字典和答案字典中的对应键值对,同时修正原代码的逻辑问题,具体实现如下:
修改后的游戏运行代码
import json import random # 读取文件,用json.load更规范安全 with open("question.txt", "r") as questions: qdic = json.load(questions) with open("answers.txt", "r") as answers: adic = json.load(answers) print("Welcome to my quiz!") play_ready = input("Are you ready to play the quiz? (yes/no) :").lower() if play_ready != "yes": print("Maybe next time!") exit() name = input("\nWhat's your name? ") points = 0 total_questions = 10 # 循环抽取10道题,每次抽取后删除对应键 for q_num in range(1, total_questions + 1): if not qdic: # 防止题目不足的情况 print("No more questions left!") break # 随机选择一个问题的键 selected_key = random.choice(list(qdic.keys())) # 获取对应的问题和正确答案 current_question = qdic[selected_key] correct_answer = adic[selected_key].lower() # 展示问题并获取玩家答案 player_answer = input(f"Question {q_num}: {current_question} ").lower() # 判断答案正误 if player_answer == correct_answer: points += 1 print("Correct!") else: print(f"Wrong answer =( The correct answer is: {adic[selected_key]}") # 从两个字典中删除已抽取的键,避免重复 del qdic[selected_key] del adic[selected_key] # 展示最终得分 print(f"\nThanks for playing, {name}! Your final score is {points}/{total_questions}")
关键修改点
- 用
json.load()替代ast.literal_eval()读取文件,更适配之前用json.dumps()写入的格式,安全性更高。 - 随机抽取字典的键而非值,这样能同时关联问题和对应的正确答案,解决原代码中判断答案不准确的问题。
- 每次抽取后用
del语句删除两个字典中对应的键,确保该问题不会被再次抽取。 - 优化循环逻辑,直接循环10次,同时增加题目不足时的判断。
- 修正答案判断逻辑,直接对比玩家答案和对应问题的正确答案,而非检查是否在所有答案中(原逻辑会导致玩家输入其他题的正确答案也得分)。
内容的提问来源于stack exchange,提问作者Nozdub
相关产品推荐
相关产品推荐

