inputUn意料之外地跳出while循环将恢复到上一次迭代Python

2024-09-30 02:14:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习python,并采纳了一个建议的想法,尝试制作一个hangman程序。我已经忙乱了一两天,代码的主要部分都在工作。它适用于1人或2人。1个玩家随机选择一个单词,2个玩家从用户那里获取一个单词/短语

一切都如我所料,除了我休息的方式。如果有人达到6/6的命中率,它会询问他们是否想再打一次。如果他们再玩一次,一切正常。如果他们第一次说不,那就按计划进行。然而,如果他们再玩一次又输了,如果他们输入“不”他们不想再玩,它会继续问他们是否想再玩。它将询问他们之前回答“是”的每个状态

示例: 他们失败了,它告诉他们“你的话是馅饼。又玩了?“是的 他们失败了,它告诉他们“你的话是大象。再玩一次?“不 “你说的是馅饼。“再来一次?”

因此,他们必须对遇到的每一个阶段说不。它在1p或2p中工作完全相同。我知道我很可能有一个低效的系统,但我可以显示1层的情况下,以帮助弥补这个代码

import pandas as pd
import numpy as np
import random

def playhangman():

    print('At any time, type "stop" to stop playing')
    print('1 player- you guess a random word. Random difficulty.')
    print('2 player- you type a word/phrase and your friend guesses.')
    playerdecision = input('Would you to play 1 or 2 player? (1p/2p):')

    if playerdecision =='1p':
        list_of_words = pd.read_csv('hangmanwords.txt')              #entire list of words as a df
        list_of_words = list_of_words.values.tolist()           #entire list of words as a list
        rand_word = random.choice(list_of_words)                #now have a single random word 1 element list

        rand_word = list(rand_word)                             #separates each letter of random word
        listedrandword = list(rand_word[0])
        listedrandword = [x.lower() for x in listedrandword]    #makes everything lowercase

        df = pd.DataFrame(listedrandword).T                     #1 by n vector instead of n by 1

        df = df.replace(r'^\s*$', np.nan, regex=True)           #replaces spaces/white space as nan
        df.fillna(0, inplace=True)                              #fills nan with 0s

        for letter in df:                                       #sets 0's to spaces to every other letter or symbol can be blanket-swapped
            if df.iloc[0,letter] == 0:
                df[letter]=' '
            elif df.iloc[0,letter] == '.':
                df[letter]='.' 
            else:
                df[letter] = '_'
        print(df)

        count=0

        while count < 6:
            letterguess = input('What letter would you like to guess? :').lower()   #makes sure inputs are regarded as lowercase
            if any(letterguess in word for word in listedrandword)==1:
                qq = [i for i,x in enumerate(listedrandword) if x == letterguess]
                for j in qq:
                    df[j] = letterguess
                print(' ')
                print(df)
                print(' ')

            elif letterguess == 'stop':
                count=7

            else:
                print('Sorry, that is wrong. This is strike',(count+1),'/6')
                count = count+1
                print('')
                print(df)
                print('')
            if df.values.tolist()[0] == listedrandword:
                print('You saved Bob! You win!')
                checker = input('Would you like to play again? (y/n)')
                if checker == 'y':
                    playhangman()
                elif checker == 'n':
                    print('Goodbye.')
                    count = 7
                else:
                    print('y/n not detected. Please type "y" or "n".')



        while count == 6:
            print('You lose, and Bob has died. The correct word was', rand_word)
            checker = input('Would you like to play again? (y/n)').lower()
            if checker == 'y':
                playhangman()
            elif checker == 'n':
                print('Goodbye.')
                count = 7
                break
            else:
                print('y/n not detected. Please only use "y" or "n".')
                break

    #need to loop this 1p still, reset counter, clear random word


    #omitted if playerdecision=='2p'
    return
playhangman()

因为“no”cases change count=7,它离开并退出,因为while's不能解释大于6的任何内容。我不明白为什么它会跳回到一次播放的所有其他内容


Tags: oftoinyoudfifascount
1条回答
网友
1楼 · 发布于 2024-09-30 02:14:58

你会想抛弃这种讨厌的模式,因为很多新程序员似乎出于某种原因而采用这种模式。模式是这样的:我正在制作一个简单的游戏,并将其完全封装在一个函数中。当球员输了或赢了,我想问他们是否愿意再玩一次。如果他们说是,我再次调用游戏功能,这样他们就可以再次玩了

这是一个很大的禁忌。你会想用一个循环来代替-每次你调用你的游戏函数时,你都在调用堆栈上推一个新的活动子例程。仅仅因为你再次调用这个函数并不意味着前一个子例程变为非活动的并且消失了——或者类似的事情。当内部子例程结束时,执行将返回到调用者—但在您的情况下,它不太可能结束,因为您不仅犯了一次罪,而且犯了两次罪,而且每次都在一个单独的while循环中。大ooof

递归(一个调用自身的函数)没有错,但是它应该被有意地使用(换句话说,如果你知道你在做什么)

看看我的简单游戏,它或多或少地模仿了代码的结构:

def start_game():
    print("Hello, welcome to my game!")
    print("Oops, you lost! Want to play again?")

    user_input = input()

    if user_input == "yes":
        start_game()

    print("When does this happen?")

start_game()

输出:

Hello, welcome to my game!
Oops, you lost! Want to play again?
yes
Hello, welcome to my game!
Oops, you lost! Want to play again?
yes
Hello, welcome to my game!
Oops, you lost! Want to play again?
yes
Hello, welcome to my game!
Oops, you lost! Want to play again?
yes
Hello, welcome to my game!
Oops, you lost! Want to play again?
no
When does this happen?
When does this happen?
When does this happen?
When does this happen?
When does this happen?
>>> 

我几乎可以肯定你没想到会有这样的结果。同样,仅仅因为调用game函数来模拟新游戏,并不意味着当前/以前的活动子例程就消失了。他们耐心地等待调用堆栈,直到执行返回给他们,他们可以完成他们的工作。这不仅在您的案例中明显不受欢迎,而且也容易出错。对于使用此结构编写的任何游戏,我都可以为您提供一个将引发RecursionError异常的输入

相关问题 更多 >

    热门问题