Python Forum
My program won't close and variables won't load correctly
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
My program won't close and variables won't load correctly
#1
My current issues are that I'm unable to close out of the program on the def try_again function and that when I load a game def load_game, the variables don't display the correct numbers(I'm not sure if this is a problem with reading the file or the values not getting to the variables Wins, Losses, and Round).



The Round variable now runs properly the first time a player decides to start a new game; however if you try to load a game the round count starts again at 1. I'm not sure if this is a problem with def_load_game and it isn't reading the correct values or whether the correct values are not being sent to the variables updating the round count. It also doesn't update the count of wins,losses, and ties that occurred during previous game.
For
def try_again():
    print()
    print("What would you like to do?")

    print("1. Play again")
    print("2. View Statistics")
    print("3. Quit")
    print()
Play again works , view statistics works, but I am unable to quit the program. What do you think is causing this problem? It tells me that it is an invalid input, but I'm not sure how to fix this.
Thanks again for your help. It is greatly appreciated.

# This program allows you to play rock, paper, scissors against the computer
import random

# Global constants for menu choices
START_NEW_GAME = 1
LOAD_GAME= 2
QUIT = 3

#Global constants for statistics
global Wins,Losses,Ties,Round
Wins=0
Losses=0
Ties=0
Round=0

# main function
def main():
    print('Welcome to Rock, Paper, Scissors!')
    

    print('1. Start New Game')
    print('2. Load Game')
    print('3. Quit')

    #Initialize a variable for the user's choice.
    choice=0
    
    

    # process menu selections until the user wants to quit the program.

    #Get the user's menu choice.
    while(True):
        try:
            choice = int(input("Enter your choice: "))
            if choice >= START_NEW_GAME and choice <= QUIT:
                break
        except ValueError:
            print("Invalid input!")
        else:
            break

    if choice==1:
        start_new_game()
    if choice==2:
        load_game()
    

# The start_new_game function allows a player to start a new game
def start_new_game():
    global name_of_player
    name_of_player = input('What is your name? ')
    print("Hello " + name_of_player + "." + " Let's play!")
    game_menu_choice()

def load_game():
    while(True):
        try:
            global name_of_player
            name_of_player = input('What is your name? ')
            infile = open(name_of_player + '.txt', 'r')
            #read three lines from the file displays wins, losses, ties.
            line1 = infile.readline()
            line2 = infile.readline()
            line3 = infile.readline()
            line4 = infile.readline()

            #close the file
            infile.close()

            #print the data that was read into memory
            Wins = int(line2)
            Losses = int(line3)
            Ties = int(line4)
        except:
            print(name_of_player + ',' +' your game could not be found')
            main()
        else:
            print("Welcome back " + name_of_player + "." + " Let's play!")
            game_menu_choice()


Round = Wins+Losses+Ties+1

# The game_menu_choice function displays the gameplay menu
# and gets a validated choice from the user

def game_menu_choice():
    Round = Wins+Losses+Ties+1
    print()
    print("Round", Round)

    print('1. Rock')
    print('2. Paper')
    print('3. Scissors')
    print('What will it be?')
    
    print()

    play_the_game()
     
    
    
    
# This program will allow the user to actually play rock, paper, scissors
def play_the_game():
    computer_choice = random.randint(1,3)
    if computer_choice==1:
        computer_choice_rock()
    if computer_choice==2:
        computer_choice_paper()
    else:
        computer_choice_scissors()
# Global constants for menu choices
ROCK = 1
PAPER = 2
SCISSORS = 3
def computer_choice_rock():
    global Wins,Losses,Ties
    # return the user's choice
    while(True):
        try:
            user_choice = int(input("Enter your choice: "))
            if user_choice >= ROCK and user_choice <= SCISSORS:
                break
        except ValueError:
            print("Invalid input!")
        else:
            break
    
    if user_choice==1:
        print("You chose Rock. The computer chose Rock. You tie!")
        Ties+=1
        try_again()
    if user_choice==2:
        print("You chose Paper. The computer chose Rock. You win!")
        Wins+=1
        try_again()
    if user_choice==3:
        print("You chose Scissors. The computer chose Rock. You lose!")
        Losses+=1
        try_again()
    else:
        print("You entered an invalid value. Please try again and enter either 1,2, or 3")
        computer_choice_rock()

def computer_choice_paper():
    # return the user's choice
    global Wins,Losses,Ties
    while(True):
        try:
            user_choice = int(input("Enter your choice: "))
            if user_choice >= ROCK and user_choice <= SCISSORS:
                break
        except ValueError:
            print("Invalid input!")
        else:
            break
    if user_choice==1:
        print("You chose Rock. The computer chose Paper. You lose!")
        Losses+=1
        try_again()
    if user_choice==2:
        print("You chose Paper. The computer chose Paper. You tie!")
        Ties+=1
        try_again()
    if user_choice==3:
        print("You chose Scissors. The computer chose Paper. You win!")
        Wins+=1
        try_again()
    else:
        print("You entered an invalid value. Please try again and enter either 1,2, or 3")
        computer_choice_paper()
def computer_choice_scissors():
    global Wins,Losses,Ties
    # return the user's choice
    while(True):
        try:
            user_choice = int(input("Enter your choice: "))
            if user_choice >= ROCK and user_choice <= SCISSORS:
                break
        except ValueError:
            print("Invalid input!")
        else:
            break
    if user_choice==1:
        print("You chose Rock. The computer chose Scissors. You win!")
        Wins+=1
        try_again()
    if user_choice==2:
        print("You chose Paper. The computer chose Scissors. You lose!")
        Losses+=1
        try_again()
    if user_choice==3:
        print("You chose Scissors. The computer chose Scissors. You tie!")
        Ties+=1
        try_again()
    else:
        print("You entered an invalid value. Please try again and enter either 1,2, or 3")
        computer_choice_scissors()

# Global constants for try_again menu choice
PLAY_AGAIN = 1
VIEW_STATISTICS = 2
QUIT = 3        
# Define Try again Function
def try_again():
    print()
    print("What would you like to do?")

    print("1. Play again")
    print("2. View Statistics")
    print("3. Quit")
    print()

    # Validate the choice.
    while(True):
        try:
            user_choice_2 = int(input("Enter your choice: "))
            if user_choice_2 >= PLAY_AGAIN and user_choice_2 <= QUIT:
                break
        except ValueError:
            print("Invalid input!")
        else:
            break   

    if user_choice_2==1:
        game_menu_choice()
    if user_choice_2==2:
        statistics()
    if user_choice_2==3:
        write_statistics()
def statistics():
    print(name_of_player,'here are your game play statistics...')
    print('Wins:', Wins)
    print('Losses:', Losses)
    print('Ties:', Ties)
    try:
        ratio = Wins/Losses
        print('Win/Loss Ratio: ', format(ratio, '.2f'))
    except ZeroDivisionError:
        print('Win/Loss Ratio: 100')
    else:
        try_again()
        

    try_again()

def write_statistics():
    #This writes four lines of data which are name of user, wins, losses, and ties
    outfile = open(name_of_player + '.txt','w')

    outfile.write(name_of_player + '\n')
    outfile.write(str(Wins) + '\n')
    outfile.write(str(Losses) + '\n')
    outfile.write(str(Ties) + '\n')

    #close the file
    outfile.close()
    
    

main()
Reply
#2
Your code structure is a mess. You need a main game loop, instead you are using recursion for everything. Let's step through a game:
  • main: I choose 1 to play a new game.
  • start_new_game: Enter 'fred'
  • game_menu_choice: The menu prints.
  • play_the_game: Computer chooses 1. (Good old rock. Nothing beats rock.)
  • computer_choice_rock: I choose 1 to beat rock. (Great minds think alike.)
  • try_again: I choose 3 to quit.
  • write_statistics: My one tie is written to a file. The function returns None. Note that this is the first function to return anything. All the functions above are still active. That's way too much for something as simple as rock paper scissors.
  • try_gain: Comes back in at the end, returns None
  • computer_choice_rock: Comes in at line 134. Then tests the conditional at 135. That's false, so it tests the conditional at 139. That's also false, so the else block on line 144 is executed, telling me I entered an invalid number.
  • computer_choice_rock: This gets called again! Now you're stuck here playing against rock. Admittedly, you could rack up a lot of wins until you hit the recursion limit...

Now, technically, you could fix this by changing the if statements on line 135 and 139 to elif statements, so they only execute if the condition I line 131 is false. But note that you would have to change computer_choice_paper and computer_choice_scissors as well. That is one problem with your code: you are not reusing code, you are duplicating it. The other is that you are using global variables, forcing the individual functions to keep track of the entire program, rather than just what is going on in that function.

Here is what I suggest. Start with one function (*ONE*!) that plays one round of RPS. Use this dictionary:

wins = {'rock': 'scissors', 'scissors': 'paper', 'paper': 'rock'}
Then you can check wins[bot_choice]. If that is equal to user_choice, the bot wins. If bot_choice equals user_choice then it's a tie. Otherwise, the user wins. That function returns (with the return statement) the user's score (1 for win, -1 for loss, 0 for tie).

Then, once the first function is done, write the second function. The second function calls the first function repeatedly until the user doesn't want to play any more. It gets the user's score from the first function and keeps track of the win/loss/draw statistics. It returns those statistics when it is finished.

Finally, write a third function that can start a new game, load a game, or quit. That one gets the statistics from the first function and writes them to a file (you can also write two other functions: one to save the stats that are passed to it as parameters, and one that loads stats and returns them.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

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