Python Forum
While loop not ending (Best of 10 dice game)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
While loop not ending (Best of 10 dice game)
#1
I am just starting to learn, this is actually my very first project, and I haven'e been able to figure out or find why the while loop does not end (under any outcome) and also why it fails to print the player scores (lines 23, 24, 32, 33, 40, 41).

I'd appreciate any help.

# Creates random numbers 
import random

#Sets start number at 0
player1_score = 0
player2_score = 0

#Repeats block until a player reaches best of 10
while player1_score or player2_score < 6:

    #Generate random number between 1 and 6 for each player
    player1_value = random.randint(1, 6)
    player2_value = random.randint(1, 6)

    #Show values
    print("Player 1 rolled: ", player1_value)
    print("Player 2 rolled: ", player2_value)

    #Selects winner of roll, increments and displays win totals, and ends game if winner is found
    if player1_value > player2_value:
        print("Player 1 wins!")
        player1_score = player1_score + 1
        print("Player 1 score is: ", player1_score)
        print("Player 2 score is: ", player2_score)
        if player1_score > 5:
            print("### Game Over ###")
            print("### Player 1 is the winner! ###")
            break
    elif player2_value > player1_value:
        print("Player 2 wins!")
        player2_score = player2_score + 1
        print("Player 1 score is: ", player1_score)
        print("Player 2 score is: ", player2_score)
        if player2_score > 5:
            print("### Game Over ###")
            print("### Player 2 is the winner! ###")
            break
    else:
        print("It's a draw!")
        print("Player 1 score is: ", player1_score)
        print("Player 2 score is: ", player2_score)
        if player1_score and player2_score == 5:
            print("The game has ended in a draw!")
            break

    #Continues if winner is not found
    input("Press enter to continue")
Reply
#2
Have a look at your while statement. It should be something like while player1_score < 6 or player2_score < 6.

I posted a go of your code modified.

import random as rnd

player1 = 0
player2 = 0
end = 6

while player1 < end or player2 < end:
    player1_roll = rnd.randint(1, 6)
    player2_roll = rnd.randint(1, 6)

    print(f'Player 1 rolled: {player1_roll}')
    print(f'Player 2 rolled: {player2_roll}')

    if player1_roll > player2_roll:
        player1 += 1
        print('Player 1 wins!')
        print(f'\nCurrent Score:\nPlayer 1: {player1}\nPlayer 2: {player2}')
        if player1 >= end:
            print(f'\nPlayer 1 wins the game!')
            print(f'Final Score:\nPlayer 1: {player1}\nPlayer2: {player2}')
            break
    elif player2_roll > player1_roll:
        player2 += 1
        print('Player 2 wins!')
        print(f'\nCurrent Score:\nPlayer 1: {player1}\nPlayer 2: {player2}')
        if player2 >= end:
            print(f'\nPlayer 2 wins the game!')
            print(f'Final Score:\nPlayer 1: {player1}\nPlayer 2: {player2}')
            break
    else:
        print('\nPlayer 1 and Player 2 ties.')
        print(f'Current Score:\nPlayer 1: {player1}\nPlayer 2: {player2}')

    input('\nPress enter to continue\n')
Output:
Player 1 rolled: 4 Player 2 rolled: 3 Player 1 wins! Current Score: Player 1: 1 Player 2: 0 Press enter to continue Player 1 rolled: 2 Player 2 rolled: 5 Player 2 wins! Current Score: Player 1: 1 Player 2: 1 Press enter to continue Player 1 rolled: 4 Player 2 rolled: 4 Player 1 and Player 2 ties. Current Score: Player 1: 1 Player 2: 1 Press enter to continue Player 1 rolled: 3 Player 2 rolled: 5 Player 2 wins! Current Score: Player 1: 1 Player 2: 2 Press enter to continue Player 1 rolled: 1 Player 2 rolled: 3 Player 2 wins! Current Score: Player 1: 1 Player 2: 3 Press enter to continue Player 1 rolled: 3 Player 2 rolled: 6 Player 2 wins! Current Score: Player 1: 1 Player 2: 4 Press enter to continue Player 1 rolled: 6 Player 2 rolled: 2 Player 1 wins! Current Score: Player 1: 2 Player 2: 4 Press enter to continue Player 1 rolled: 1 Player 2 rolled: 4 Player 2 wins! Current Score: Player 1: 2 Player 2: 5 Press enter to continue Player 1 rolled: 3 Player 2 rolled: 5 Player 2 wins! Current Score: Player 1: 2 Player 2: 6 Player 2 wins the game! Final Score: Player 1: 2 Player 2: 6
BashBedlam and K3nidi like this post
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
This does not do what you think it does:
player1_score or player2_score < 6
In Python "a or b" returns "a" if bool(a) is Tue, otherwise it returns "b". In Python most things are True when converted to a bool. False, None, 0, zero length strings and empty collections (lists, sets, dictionaries) are False when converted to bool.

Converting your expression "player1_score or player2_score < 6" to a or b, a = "player1_score" and b = "player2_score < 6"". bool(player1_score) is False when player1_score == 0, otherwise it is True. bool(player2_score < 6) is True if player2_score < 6.

Remembering that "a or b" returns "a" of bool(a) is True, The only way to exit the loop is for player1's score to be zero and for player2's score to be >= 6. In other words your loop can only exit if player2 wins the first 6 games.

You could modify the loop to compare both scores;
while player1_score < 6 and player2_score < 6:
This would work, but I think I prefer this:
while True:
The only time I put the ending condition in the while statement is when the ending condition is really simple. If there is any complication in deciding when to end the loop I set the loop to run forever, and break out of the loop when the complicate condition is met.

I modified you program to work with more than two players.
import random

players = ["Abby", "Sam", "David", "Michelle"]
scores = [0] * len(players)
 
while True:
    rolls = [random.randint(1, 6) for _ in players]
    for player, roll in zip(players, rolls):
        print(f"{player} roll = {roll}")
 
    if len(set(rolls)) == 1:
        print("It's a draw\n")
    else:
        # Highest roll wins wound and gets the point
        winner = rolls.index(max(rolls))
        scores[winner] += 1
        print(f"{players[winner]} wins\n")

    # Print everyone's score
    for player, score in zip(players, scores):
       print(f"{player} score is: {score}")

    if max(scores) >= 6:
        break  # Game over when someone reaches 6 points

    input("Press enter to continue\n")

winner = scores.index(max(scores))
print("### Game Over ###")
print(f"### {players[winner]} is the winner! ###")
I could but the condition in the while statement. It is still pretty simple:
while max(scores) < 6:
But to prevent having to press "enter" after the game winning roll I need some conditional logic like this:
if max(scores) < 6:
    input("Press enter to continue\n")
I would rather check scores only once.
K3nidi likes this post
Reply
#4
Thank you both. Your replies have been really helpful and I am going use them to learn about the functions and everything you used.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  For Loop and Use of Brackets to Modify Dictionary in Tic-Tac-Toe Game new_coder_231013 7 2,263 Dec-28-2021, 11:32 AM
Last Post: new_coder_231013
  loop adventure game ilikedofs 1 1,712 May-26-2021, 12:43 AM
Last Post: bowlofred
  Designing a "game" loop api pitosalas 2 2,487 Jun-07-2020, 03:20 PM
Last Post: pitosalas
  Ending the Program Twoshawns 2 2,098 May-19-2020, 02:24 AM
Last Post: menator01
  Python: Call function with variabele? Ending in error. efclem 5 2,951 Apr-22-2020, 02:35 PM
Last Post: buran
  game of the goose - dice problem koop 4 3,494 Apr-11-2020, 02:48 PM
Last Post: ibreeden
  ending process hrparra 1 1,912 Jan-07-2020, 07:40 PM
Last Post: ibreeden
  Dice game Mazzo76 1 1,974 Feb-26-2019, 11:55 AM
Last Post: Larz60+
  Issue with my 'roll the dice simulation'-exercise (cannot break out of the loop) Placebo 2 3,515 Sep-30-2018, 01:19 PM
Last Post: Placebo
  Making a percentile dice roller and dice roller Fixer243 2 3,247 Sep-30-2018, 12:18 PM
Last Post: gruntfutuk

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020