Hangman猜词游戏中for循环为何会删除重复字母?
猜词游戏(Hangman)重复字母被去重问题排查
问题现象
开发的Hangman游戏中,单词里的重复字母会被自动删除,比如单词"clammer"会显示为"clamer",导致游戏逻辑错误。
问题代码
import json import random #variables and classes class currentlives: onelt = f" _____ \n | \n | \n | \n | \n | \n | \n | \n | \n___|___" twolt = f" _____ \n | ___ \n | / \ \n | \___/ \n | \n | \n | \n | \n | \n___|___" thrlt = f" _____ \n | ___ \n | / \ \n | \___/ \n | | \n | - \n | | \n | | \n | \n___|___" foult = f" _____ \n | ___ \n | / \ \n | \___/ \n | | \n | ------- \n | | \n | | \n | \n___|___" fivlt = f" _____ \n | ___ \n | / \ \n | \___/ \n | | \n | ------- \n | | \n | | \n | / \n___|___" sixlt = f" _____ \n | ___ \n | / \ \n | \___/ \n | | \n | ------- \n | | \n | | \n | / \ \n___|___ (LAST LIFE)" lives_counter = 0 Vals = {} letters_used = [] #defining function zone: def Turn(): global lives_counter global Guesses while lives_counter <= 4: if lives_counter == 0: print(currentlives.onelt, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() elif lives_counter == 1: print(currentlives.twolt, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() elif lives_counter == 2: print(currentlives.thrlt, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() elif lives_counter == 3: print(currentlives.foult, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() elif lives_counter == 4: print(currentlives.fivlt, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() elif lives_counter == 5: print(currentlives.sixlt, f"you have used: {letters_used}, and the current letters look like {Guesses}, now which letter would you like to guess next?") pguess = input() check(pguess) if Win() == 10: print("Congrats you won!") break Turn() else: print(Vals) else: print(f"GAME OVER, sorry that might've been impossible but you ran out of lives, please play again but here's the answer {WChoice}") def TurnDebug(): global Vals print(Vals) def check(guess): global Guesses global lives_counter if guess in Vals: Vals[guess] = guess Guesses = list(Vals.values()) else: letters_used.append(guess) lives_counter += 1 def Win(): x = 0 winvar = 10 for value in Vals: if value == Vals[value]: x += 1 if x == len(WChoice): return winvar #word picker + stuff: def Word_picker(): global Rword global Words global Dictonaryftg with open(r"C:\Users\Larry\Downloads\EnglishDictionary.json", 'r') as f: Dictonaryftg = json.load(f) Words = list(Dictonaryftg.keys()) Rword = str(random.choice(Words)) return Rword WChoice = str(Word_picker()) for letter in WChoice: Vals[letter] = "_" Guesses = list(Vals.values()) Turn()
问题根源
你用**字典Vals**存储单词的字母状态,但字典的键具有唯一性。处理含重复字母的单词时,比如"clammer"(包含两个'm'和两个'r'),循环for letter in WChoice: Vals[letter] = "_"会覆盖重复字母的键,最终字典中每个字母仅保留一个,导致Guesses列表丢失重复字母的位置,显示为去重后的结果。
同时,Win()函数用字典键的数量与原单词长度对比,也会因去重导致判断逻辑错误——比如原单词长度为7,字典键数量仅为5,永远无法满足x == len(WChoice)的获胜条件。
解决方案
将存储字母状态的结构从字典改为列表,保留所有字母的位置(包括重复字母):
- 初始化
Guesses为列表,每个字母对应一个下划线:
WChoice = str(Word_picker()) Guesses = ["_" for _ in WChoice] # 替换原字典初始化逻辑
- 修改
check函数,遍历列表更新所有匹配的字母:
def check(guess): global Guesses global lives_counter if guess in WChoice: # 遍历列表,把所有匹配的下划线替换为猜中的字母 for i in range(len(WChoice)): if WChoice[i] == guess: Guesses[i] = guess else: if guess not in letters_used: # 避免重复记录已猜过的错误字母 letters_used.append(guess) lives_counter += 1
- 修改
Win()函数,直接检查Guesses中是否还有下划线:
def Win(): if "_" not in Guesses: return 10
- 删除原代码中
Vals字典的相关定义和使用,因为已不再需要。
修改后的核心代码片段:
lives_counter = 0 letters_used = [] Guesses = [] # 用列表存储字母状态 # 保留Turn函数不变 def check(guess): global Guesses global lives_counter if guess in WChoice: for i in range(len(WChoice)): if WChoice[i] == guess: Guesses[i] = guess else: if guess not in letters_used: letters_used.append(guess) lives_counter += 1 def Win(): if "_" not in Guesses: return 10 # 保留Word_picker函数不变 WChoice = str(Word_picker()) Guesses = ["_" for _ in WChoice] Turn()
修改后,重复字母会被正确保留,比如"clammer"会显示为["_", "_", "_", "_", "_", "_", "_"],猜中'm'后会变成["_", "_", "_", "m", "m", "_", "_"],完全符合Hangman游戏逻辑。
内容的提问来源于stack exchange,提问作者TheCube541
相关产品推荐
相关产品推荐

