简体   繁体   中英

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. How can I fix this to get my while loop to run through both players' turns.

I have tried adding 'continue' and 'break' in various places and have tried switching the boolean values up, but nothing seems to work.

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.

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.

The Sequential flow is:

  1. Enter the first loop => True # so true
  2. Enter the inner loop => first_player_move is True # so true
  3. Execute inner block then breaks and go to first loop and repeat the steps above

  4. Enter the first loop => True # so true

  5. Enter the inner loop => 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).

I recommend moving the print('It is now ' + player2_name + "'s turn.") into your if and modifying thusly:

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. Is this correct?

If so, there's also a slight optimization that you can do to shrink the size of data.txt. Strip out all of the words which are 3 or less characters and you can remove the len(word_fragment) > 3 constraint.

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?

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.

Further style suggestion. There is no need to use loops for the player turns:

  • Keep the whole thing in your big "while True" loop:
  • Prompt for player1 input
  • Test for player1 loss (ie fragment in data.txt)
  • Prompt for player2 input
  • Test for player2 loss
  • 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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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