2012-03-02 4 views
2

Le principal problème que je rencontre est d'essayer d'obtenir le total des pertes perdues et cravates lorsque l'utilisateur joue avec l'ordinateur (fonction aléatoire). Mais je continue à recevoir cette erreur chaque fois que je saisis 1, 2 ou 3 pour des ciseaux de papier de roche pour player_choice.S'il vous plaît regarder mon programme de ciseaux de papier de pierre pour python

Welcome to a game of paper, rock, scissors! 
Please input the correct number according 
to the object. 
Select rock(1), paper(2), or scissors(3): 2 
Computer chose ROCK . 
You chose PAPER . 
Traceback (most recent call last): 
    File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line  
114, in <module> 
    File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 
43, in main 
    File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 
106, in determine_winner 
builtins.UnboundLocalError: local variable 'win' referenced before assignment 

Il est clair que la question d'une variable locale. Y a-t-il d'autres solutions? Voici mon code:

#import the library function "random" so that you can use it for computer 
#choice 
import random 

#define main 
def main(): 
    #assign win, lose, and tie variables to zero so that later it can be added 
    #and displayed 
    win = 0 
    lose = 0 
    tie = 0 

    #control loop with 'y' variable 
    play_again = 'y' 

    #start the game 
    while play_again == 'y': 
     #make a welcome message and give directions 
     print('Welcome to a game of paper, rock, scissors!') 
     print('Please input the correct number according') 
     print('to the object.') 

     #write computer and players choices as value returning functions and 
     #assign them to variables 
     computer_choice = get_computer_choice() 
     player_choice = get_player_choice() 

     #print outcome 
     print('Computer chose', computer_choice, '.') 
     print('You chose', player_choice, '.') 

     #determine who won by defining a function 
     determine_winner(computer_choice, player_choice) 

     #ask the user if they want to play again 
     play_again = input("Play again? Enter 'y' for yes or 'n' for no. ") 

    #print results 
    print('Your total wins are', win, '.') 
    print('Your total losses are', lose, '.') 
    print('Your total ties are', tie, '.') 

#define computer choice 
def get_computer_choice(): 
    #use imported random function from library 
    choice = random.randint(1,3) 

    #assign what the computer chose to rock, paper, or scissors 
    if choice == 1: 
     choice = 'ROCK' 
    elif choice == 2: 
     choice = 'PAPER' 
    else: 
     choice = 'SCISSORS' 

    #return value 
    return choice 

#define player choice 
def get_player_choice(): 
    #assign input to variable by prompting user 
    choice = int(input("Select rock(1), paper(2), or scissors(3): ")) 

    #use while function if user inputs the invalid selection 
    while choice != 1 and choice != 2 and choice != 3: 
     print('The valid numbers are rock(type in 1), paper(type in 2),') 
     print('or scissors(type in 3).') 
     choice = int(input('Enter a valid number please: ')) 

    #assign what the player chose to rock, paper, or scissors 
    if choice == 1: 
     choice = 'ROCK' 
    elif choice == 2: 
     choice = 'PAPER' 
    else: 
     choice = 'SCISSORS' 

    #return value 
    return choice 

#determine the winner by assigning the assigned variables 
def determine_winner(computer_choice, player_choice): 
    #if its a tie, add 1 to tie variable and display message 
    if computer_choice == player_choice: 
     tie += 1 
     print("It's a tie!") 

    #if its a win, add to win variable and display message 
    elif computer_choice == 'SCISSORS' and player_choice == 'ROCK': 
     win += 1 
     print('ROCK crushes SCISSORS! You win!') 
    elif computer_choice == 'PAPER' and player_choice == 'SCISSORS': 
     win += 1 
     print('SCISSORS cut PAPER! You win!') 
    elif computer_choice == 'ROCK' and player_choice == 'PAPER': 
     win += 1 
     print('PAPER covers ROCK! You win!') 

    #if it does not match any of the win criteria then add 1 to lose and 
    #display lose message 
    else: 
     lose += 1 
     print('You lose!') 
main() 

Répondre

1

La fonction determine_winner() ne peut pas voir les variables win, tie et lose que vous avez défini dans main(). Par conséquent, vous ne pouvez pas faire win +=1.

De toute façon, vous n'utilisez généralement pas une routine main() en Python (j'ai vu récemment quelques questions qui les utilisent - celui qui enseigne cela?), Mais même si vous déplacez son contenu au niveau supérieur de la programme, cela ne fonctionnerait pas car win += 1 échouerait toujours pour la même raison.

Vous pouvez définir des variables locales win, tie et lose dans determine_winner() et ont le retourner leurs valeurs, puis ajouter dans le code de haut niveau ceux des variables respectives. En fait, vous n'avez même pas besoin de ces variables dans cette fonction.

Par exemple:

def determine_winner(computer_choice, player_choice): 
    #if its a tie, add 1 to tie variable and display message 
    if computer_choice == player_choice: 
     print("It's a tie!") 
     return 0 

    #if its a win, add to win variable and display message 
    elif computer_choice == 'SCISSORS' and player_choice == 'ROCK': 
     print('ROCK crushes SCISSORS! You win!') 
     return 1 
    elif computer_choice == 'PAPER' and player_choice == 'SCISSORS': 
     print('SCISSORS cut PAPER! You win!') 
     return 1 
    elif computer_choice == 'ROCK' and player_choice == 'PAPER': 
     print('PAPER covers ROCK! You win!') 
     return 1 

    #if it does not match any of the win criteria then add 1 to lose and 
    #display lose message 
    else: 
     print('You lose!') 
     return -1 

et au niveau supérieur:

result = determine_winner(computer_choice, player_choice) 
if result == -1: 
    lose += 1 
elif result == 0: 
    tie += 1 
else: 
    win += 1 
+0

Merci beaucoup! J'ai regardé ce problème pendant des heures! –

+2

Même si vous n'utilisez pas une fonction 'main()', c'est toujours une bonne idée de placer votre code principal sous une instruction 'if __name__ ==" __main __ ":'. –

+0

La ligne 'if __name__ ==" __main__ ": main()' en bas est généralement faite par tous ceux que j'ai vus, en fait. Je pense qu'un but est que le fichier puisse être importé sans que tout le code de 'main' ne soit exécuté. Vous pouvez donc utiliser une fonction hypothétique 'randRGB()' ou quelque chose dans le fichier d'un script externe. – SimonT

0

Python utilise une portée lexicale. Cela signifie que si une variable est définie à l'intérieur d'une fonction, le code en dehors de cette fonction ne peut pas le voir (sauf s'il est marqué global).

Une solution rapide et sale serait de marquer win, et toutes les autres variables qui doivent être vues de l'extérieur main, comme global. Une meilleure solution serait de restructurer votre code.

+0

Vous devez d'abord les déplacer en dehors de 'main()' ou ils ne seront pas globaux de toute façon. –

+0

Avec une déclaration 'global', ils le seront. Pas que ce soit la solution la plus élégante. – Taymon

+0

Non. Actuellement, ils ne sont pas définis au niveau supérieur du module. L'instruction 'global' ne rend pas les variables locales globales. Il indique à la fonction de * rechercher * la variable référencée dans la portée globale au lieu de créer une variable locale. Cela ne fonctionne que s'il existe déjà * une telle variable globale. –

1

Vous pouvez faire gagner, perdre et lier vos variables à l'échelle mondiale. Ici, ils ne le sont pas. How to make them global

Editer: Je suis d'accord que rendre global n'est pas une bonne solution.

+0

Je ne pense pas que ce soit une bonne solution. Premièrement, même si vous les faites globaux, cela ne marche toujours pas, sauf si vous utilisez aussi 'global win' au début de' determ_winner() ', et deuxièmement, les variables globales ne sont presque jamais une bonne idée. –

+0

Je suis d'accord que le retour du résultat est une meilleure solution que l'utilisation de globals. Je pensais juste qu'Oiugghog Jkhkh demandait comment utiliser les variables globales. – bmkorkut

+0

Non, vous ne devriez pas. –

Questions connexes