You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Hangman游戏:ask_for_name与menu关联play函数失败问题

Python Hangman游戏函数关联问题解决

问题描述

开发Python版Hangman游戏时,尝试将ask_for_name()和menu()函数与play()函数关联,但遇到以下问题:

  • 游戏启动后直接进入play()游戏流程,未执行用户名输入和菜单环节
  • 游戏结束后选择“否”重启,回到用户名输入和菜单,但此时选择“P”启动游戏会触发错误
  • 调整函数定义位置后,要么函数无法正常运行,要么不会被调用

问题代码

def ask_for_name():
while True:
    name = input(YELLOW_COLOR + "Please Enter Your Name:\n")
    
    if not name.isalpha():
        print("Name must be letters only\n")
    else:
        print(f"Hello {name}, Welcome to Chris's Hangman and Good Luck!\n")
        menu()
return name   


def menu():
"""
menu function which gives the user two options
- Press 1 to play or 2 for instructions
- only accepts valid keys or error message comes up
"""
while True:
    user_input = input("Press P to Play game\nPress I for Instructions\n").upper()
    if user_input == "P":
        play()
    elif user_input == "I":
        print(
            "1.The computer will generate a random word and it's\n"
            "your task to guess the letters from the word.\n"
            "2.To guess, type a letter of your choice and hit enter.\n"
            "3.If you guess correctly, the letter will be revealed.\n"
            "4.If you guess incorrectly, you will lose a life and \n"
            " the Hangman will start to appear.\n"
            "5.You have 8 lives to guess the correct word.\n"

            "Good Luck!\n")
        enter_input = input("Press Enter to go back to the menu\n").upper()
        if enter_input == "":
            menu()
        else:
            print(RED_COLOR + "Oops look's like you pressed the wrong key!\n")
            
    else:
        print("Invalid Character, please try again!\n")



        
word = "dog" #random.choice(WORDS)
word = word.upper()
reveal = list(len(word)*'_')
lives = 8
game_is_won = False

def check_letter(letter, word):
global reveal
for i in range(0,len(word)):
    letter = word[i]
    if guess == letter:
        reveal[i] = guess
if '_' not in reveal:
    return True
else:
    return False


def restart_game():
"""
Gives player option to restart, otherwise returns to menu
"""
game_restart = False

while not game_restart:
    restart = input("Would you like to play again?"
                    "Y/N").upper()
    try:
        if restart == "Y":
            game_restart = True

            play()

        elif restart == "N":
            game_restart = True
            print("\n")
            header()
            ask_for_name()
            menu()

        else:
            raise ValueError(
            "You must type in Y or N"
            )

    except ValueError as e:
        print("\n You must type in Y or N Please try again.\n")


def play():
os.system("clear")
header()
print(hangman[8-lives])
print(' '.join([str(e) for e in reveal]))
print(f"You have {lives} lives")


while game_is_won == False and lives > 0:
play()
guess = input('Guess a letter or an entire word:')
guess = guess.upper()

if guess == word:
    game_is_won = True
    reveal = word
elif len(guess) == 1 and guess in word:
    game_is_won = check_letter(guess, word)
else:
    lives -= 1

if game_is_won:
    player_won()
    print("WELL DONE")
    
else:
    player_lost()
    print(f"YOU FAILED the word was: {word}")
    

restart_game()

问题分析

  1. 全局变量未重置:word、reveal、lives、game_is_won等状态变量定义为全局,第二次进入游戏时仍使用上一次的状态,导致逻辑混乱报错
  2. 函数缩进错误:ask_for_name()中的while循环、check_letter()中的for循环、play()函数内代码均未正确缩进,导致函数逻辑无法正常执行
  3. 递归调用陷阱:menu()中选择“返回菜单”时递归调用menu(),会导致函数调用栈不断累积,最终引发异常
  4. 执行流程错误:程序启动后直接执行了play()外的while循环,跳过了ask_for_name()和menu()的初始化流程
  5. 函数逻辑错误:check_letter()未使用传入的letter参数,反而依赖全局的guess变量,导致猜字母逻辑失效

解决方案

关键修改点

  • 将游戏状态变量移至play()函数内部,每次启动游戏时初始化新状态
  • 修复所有函数的缩进错误,确保代码块逻辑正确
  • 用循环替代递归调用,避免函数栈溢出
  • 调整程序入口,从调用ask_for_name()开始
  • 修正check_letter()的逻辑,使用传入的参数实现字母匹配
  • 移除play()外的冗余循环,将游戏主循环整合到play()函数内

修改后的完整代码

import os

# 补充缺失的常量和辅助函数
YELLOW_COLOR = "\033[93m"
RED_COLOR = "\033[91m"
RESET_COLOR = "\033[0m"
hangman = [
    """
      +---+
          |
          |
          |
         ===
    """,
    """
      +---+
      O   |
          |
          |
         ===
    """,
    """
      +---+
      O   |
      |   |
          |
         ===
    """,
    """
      +---+
      O   |
     /|   |
          |
         ===
    """,
    """
      +---+
      O   |
     /|\\  |
          |
         ===
    """,
    """
      +---+
      O   |
     /|\\  |
     /    |
         ===
    """,
    """
      +---+
      O   |
     /|\\  |
     / \\  |
         ===
    """
]

def header():
    print(RESET_COLOR + "=== HANGMAN GAME ===")

def player_won():
    print(RESET_COLOR + "🎉 YOU WON! 🎉")

def player_lost():
    print(RESET_COLOR + "💀 GAME OVER 💀")

def ask_for_name():
    while True:
        name = input(YELLOW_COLOR + "Please Enter Your Name:\n" + RESET_COLOR)
        if not name.isalpha():
            print("Name must be letters only\n")
        else:
            print(f"Hello {name}, Welcome to Chris's Hangman and Good Luck!\n")
            return name

def menu():
    """菜单函数:提供开始游戏和查看说明选项"""
    while True:
        user_input = input("Press P to Play game\nPress I for Instructions\n").upper()
        if user_input == "P":
            play()
        elif user_input == "I":
            print(
                "1. 电脑会生成一个随机单词,你的任务是猜出单词中的字母\n"
                "2. 输入一个字母并回车进行猜测\n"
                "3. 猜对则字母会被显示出来\n"
                "4. 猜错会减少一条生命,同时绞刑架图案逐步显示\n"
                "5. 你有8条生命来猜出正确单词\n\n"
                "祝你好运!\n"
            )
            input("按回车键返回菜单...")
            continue
        else:
            print("无效输入,请重新尝试!\n")

def check_letter(guess_letter, word, reveal_list):
    """检查字母是否在单词中,更新显示列表,返回是否猜中所有字母"""
    found = False
    for i in range(len(word)):
        if word[i] == guess_letter:
            reveal_list[i] = guess_letter
            found = True
    return '_' not in reveal_list

def restart_game():
    """询问玩家是否重启游戏,返回菜单或重新开始"""
    while True:
        restart = input("Would you like to play again? Y/N\n").upper()
        if restart == "Y":
            play()
            break
        elif restart == "N":
            print("\n")
            header()
            ask_for_name()
            menu()
            break
        else:
            print("必须输入Y或N,请重新尝试!\n")

def play():
    # 每次游戏初始化全新状态
    os.system("clear")
    header()
    word = "DOG"  # 替换为random.choice(WORDS)
    reveal = list(len(word)*'_')
    lives = 8
    game_is_won = False

    while not game_is_won and lives > 0:
        print(hangman[8 - lives])
        print(' '.join(reveal))
        print(f"你还有 {lives} 条生命\n")
        
        guess = input('猜一个字母或整个单词:').upper()
        
        if guess == word:
            game_is_won = True
            reveal = list(word)
        elif len(guess) == 1 and guess in word:
            game_is_won = check_letter(guess, word, reveal)
        else:
            lives -= 1
            print(f"错误!剩余生命:{lives}")

    if game_is_won:
        player_won()
        print(f"正确单词是:{word}")
    else:
        player_lost()
        print(f"正确单词是:{word}")
    
    restart_game()

# 程序入口
if __name__ == "__main__":
    header()
    ask_for_name()
    menu()

说明

  • 补充了颜色控制、绞刑架图案、头部提示等缺失的辅助内容
  • 所有游戏状态变量在play()内初始化,确保每次游戏都是全新状态
  • 菜单返回逻辑改为循环continue,避免递归调用导致的栈溢出
  • check_letter()改为接收参数,不再依赖全局变量,逻辑更清晰
  • 程序通过if __name__ == "__main__"启动,确保正确的初始化流程

内容的提问来源于stack exchange,提问作者chris-t93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:01:55