简体   繁体   English

如何修复 Python 中的重复 while 循环

[英]How to fix repeating while loop in Python

I am trying to use a while loop to alternate turns between two users but my code gets stuck on the "while first_player_move is True:" loop.我正在尝试使用 while 循环在两个用户之间交替轮流,但我的代码卡在“while first_player_move is True:”循环中。 How can I fix this to get my while loop to run through both players' turns.我怎样才能解决这个问题,让我的 while 循环在两个玩家的回合中运行。

I have tried adding 'continue' and 'break' in various places and have tried switching the boolean values up, but nothing seems to work.我尝试在不同的地方添加 'continue' 和 'break' 并尝试切换布尔值,但似乎没有任何效果。

word_fragment = ''
        first_player_move = True
        while True:
            while first_player_move is True:
                added_letter = input('Which single letter would you like to add to the fragment? ')
                word_fragment += added_letter
                print('The current word fragment is: ' + word_fragment)
                print('It is now ' + player2_name + "'s turn.")
                if word_fragment in open('data.txt').read() and len(word_fragment) > 3:
                    print('I am sorry, you just lost. ' + player2_name + ' is the winner!')
                    # call a function to end the game
                    break

            while first_player_move is False:
                added_letter = input('Which single letter would you like to add to the fragment? ')
                word_fragment += added_letter
                print('The current word fragment is: ' + word_fragment)
                print('It is now ' + player1_name + "'s turn.")
                if word_fragment in open('data.txt').read() and len(word_fragment) > 3 :
                    print('I am sorry, you just lost. ' + player1_name + ' is the winner!')
                    # call a function to end the game
                    break

I expect the output to run through each players' turn and end up printing "it is now 'the next players' turn" but instead it keeps printing out the same name for the next players turn which is telling me that the code is stuck in the first of the two while loops.我希望输出能够通过每个玩家的回合并最终打印“现在是‘下一个玩家’回合”,但它会不断为下一个玩家回合打印出相同的名称,这告诉我代码被卡在了两个 while 循环中的第一个。

Since first_player_move doesn't change to false , when the inner loop ends, the outer starts a new cycle and call the inner again.由于first_player_move不会更改为false ,当内部循环结束时,外部开始一个新的循环并再次调用内部循环。

The Sequential flow is:顺序流是:

  1. Enter the first loop => True # so true进入第一个循环 => True #所以真的
  2. Enter the inner loop => first_player_move is True # so true进入内循环 => first_player_move is True # so true
  3. Execute inner block then breaks and go to first loop and repeat the steps above执行内部块然后breaks并转到第一个循环并重复上述步骤

  4. Enter the first loop => True # so true进入第一个循环 => True #所以真的

  5. Enter the inner loop => first_player_move is True # so true进入内循环 => first_player_move is True # so true

You're never setting first_player_move to false in the first loop (also never setting it to true in the second loop).您永远不会在第一个循环中将 first_player_move 设置为 false(也永远不会在第二个循环中将其设置为 true)。

I recommend moving the print('It is now ' + player2_name + "'s turn.") into your if and modifying thusly:我建议将 print('It now is ' + player2_name + "'s turn.") 移动到您的 if 中并进行如下修改:

if word_fragment in open('data.txt').read() and len(word_fragment) > 3:
    print('I am sorry, you just lost. ' + player2_name + ' is the winner!')
    # call a function to end the game
    break
else:
    print('It is now ' + player2_name + "'s turn.")
    first_player_move = False

Comparable mod to the 2nd player loop.与第二个播放器循环相当的模组。

I'd also like to confirm your win/loss conditions.我还想确认您的输赢条件。 They way I read your code, if someone is responsible for creating a fragment which is contained in data.txt and the fragment is greater than 3 characters, they lose.他们以我阅读您的代码的方式,如果有人负责创建包含在 data.txt 中的片段并且该片段大于 3 个字符,他们就会失败。 Is this correct?这样对吗?

If so, there's also a slight optimization that you can do to shrink the size of data.txt.如果是这样,您还可以做一些轻微的优化来缩小 data.txt 的大小。 Strip out all of the words which are 3 or less characters and you can remove the len(word_fragment) > 3 constraint.去掉所有 3 个或更少字符的单词,您可以删除 len(word_fragment) > 3 约束。

One further issue I expect you'll encounter... what happens in the case where players get up to a sizeable fragment and have still not matched anything in data.txt?我希望你会遇到另一个问题……如果玩家获得了一个相当大的片段并且仍然没有匹配 data.txt 中的任何内容,会发生什么?

You may want to think about creating a tie condition.您可能需要考虑创建平局条件。 Eg At the end of your main "while True" loop, test for length > the longest word in data.txt and call it a tie.例如,在主“while True”循环结束时,测试长度 > data.txt 中最长的单词并将其称为平局。

Further style suggestion.进一步的风格建议。 There is no need to use loops for the player turns:玩家回合无需使用循环:

  • Keep the whole thing in your big "while True" loop:把整个事情放在你的大“while True”循环中:
  • Prompt for player1 input提示玩家 1 输入
  • Test for player1 loss (ie fragment in data.txt)测试 player1 丢失(即 data.txt 中的片段)
  • Prompt for player2 input提示 player2 输入
  • Test for player2 loss测试 player2 丢失
  • Test for fragment length > max length测试片段长度 > 最大长度
  • Back to the top of the loop回到循环的顶部
  • break on player loss or max fragment length播放器丢失或最大片段长度中断
  • no need to toggle first_player_move True/False无需切换 first_player_move 真/假

Bonus points if you can get by with only one chunk of prompt_then_test code and toggle between the player names on each pass.如果您可以只使用一个 prompt_then_test 代码块并在每次传递时在玩家名称之间切换,则可以获得奖励积分。

The following approach might work better.以下方法可能效果更好。 The aim is to try and avoid repeating code and instead use variables to help:目的是尽量避免重复代码,而是使用变量来帮助:

word_fragment = ''
first_player_move = True

while True:
    player_name = player1_name if first_player_move else player2_name
    print(f"It is now {player_name}'s turn.")

    added_letter = input(f'{player_name}: Which single letter would you like to add to the fragment? ')
    word_fragment += added_letter

    print('The current word fragment is: ', word_fragment)

    if word_fragment in open('data.txt').read() and len(word_fragment) > 3:
        print('I am sorry, you just lost. ' + player2_name + ' is the winner!')
        break  # call a function to end the game

    first_player_move = not first_player_move

This uses player_name to hold the current player's name and first_player_move is toggled between True and False for each loop.这使用player_name来保存当前玩家的名字,并且first_player_move在每个循环的TrueFalse之间切换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM