2016-07-29 5 views
0

Le programme est censé mettre à jour la valeur de la variable globale int_choice chaque fois qu'un joueur (c'est un jeu de pong)Problème avec une variable globale mise en

int_choice ne peut avoir une valeur de 1 ou 0. Si elle est 1, la fonction left_or_right "dit" la balle pour aller à droite, si c'est 0, la balle va à gauche.

int_choice est mis à jour à quelques endroits: au début, il est initialisé, puis dans la fonction left_or_right(), puis dans la fonction draw(). Chaque fois que l'utilisateur marque des points, la balle doit être réapparue du centre de la table vers cet utilisateur, mais la balle réapparaît toujours deux fois dans la même direction, puis deux fois dans la direction opposée et ainsi de suite, peu importe qui était le dernier à marquer.

Voici le code:

import random 

int_choice = random.randint(0,1) 
direc = None 

def left_or_right(): 
    global direc, int_choice 
    if int_choice == 0: 
     direc = "LEFT" 
    elif int_choice == 1: 
     direc = "RIGHT" 
    return direc 

def spawn_ball(direction): 
    left_or_right() 
    global ball_pos, ball_vel # these are vectors stored as lists 
    ball_pos = [WIDTH/2, HEIGHT/2] 
    if direction == "LEFT": 
     ball_vel[0] = (random.randrange(12, 25)*(-0.1)) 
     print "Velocity[0]: ", ball_vel[0] 
     ball_vel[1] = (random.randrange(6, 19)*(-0.1)) 
    elif direction == "RIGHT": 
     ball_vel[0] = (random.randrange(12, 25)*(0.1)) 
     print "Velocity[0]: ", ball_vel[0] 
     ball_vel[1] = (random.randrange(6, 19)*(-0.1)) 
     print "Velocity[1]: ", ball_vel[1] 

def new_game(): 
    global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel, direc 
    global score1, score2, 
    spawn_ball(direc) 
    score1 = 0 
    score2 = 0 

def draw(canvas): 
    global remaining_names, score1, score2, paddle1_pos, paddle2_pos,   ball_pos, ball_vel, BALL_RADIUS, direc 
    global int_choice 


    # update ball 
    ball_pos[0] += ball_vel[0] 
    ball_pos[1] += ball_vel[1] 
    if ball_pos[1] - BALL_RADIUS <= 0: 
     ball_vel[1] = ball_vel[1] + (ball_vel[1] * (-2))  
    elif ball_pos[1] + BALL_RADIUS >= HEIGHT: 
     ball_vel[1] = ball_vel[1] + (ball_vel[1] * (-2)) 
    elif ball_pos[0] - BALL_RADIUS <= (0 + PAD_WIDTH): 
     if (ball_pos[1] > paddle1_pos) and (ball_pos[1] < (paddle1_pos + PAD_HEIGHT)): 
      ball_vel[0] = ball_vel[0] + (ball_vel[0] * (-2.1)) 
     else: 
      int_choice = 1 
      spawn_ball(direc) 
      score2 = score2 + 1 

    elif (ball_pos[0] + BALL_RADIUS) >= (WIDTH - PAD_WIDTH): 
     if (ball_pos[1] > paddle2_pos) and (ball_pos[1] < (paddle2_pos + PAD_HEIGHT)): 
      ball_vel[0] = ball_vel[0] + (ball_vel[0] * (-2.1)) 
     else: 
      int_choice = 0 
      spawn_ball(direc) 
      score1 = score1 + 1 
+0

'random.randint (0,1)' est un alias pour 'random.randrange (2)'. Envisagez d'utiliser le plus tard. –

+1

Pourquoi utilisez-vous des * deux * globals qui signifient la même chose? Et votre fonction 'left_or_right()' pourrait juste être remplacée par une liste: 'directions = ['LEFT', 'RIGHT']', et 'directions [int_choice]' traduirait l'entier en texte chaque fois que vous avez besoin du texte. –

+0

Vous passez également dans la direction 'spawn_ball()', qui appelle ensuite 'left_or_right()' aussi bien *. Pourquoi passer dans la direction, puis appeler une fonction pour le régler à nouveau? La fonction renvoie également la direction, mais vous ignorez la valeur de retour partout. –

Répondre

4

Vous transmettez le ancien valeur de direc, avant que left_or_right s'appelle.

Dites, vous définissez int_cohice-1:

int_choice = 1 
spawn_ball(direc) # old value of `direc`, nothing changed this yet 

puis à spawn_ball():

def spawn_ball(direction): 
    left_or_right() 

si direction est réglé la ancienne valeur, mais left_or_right() ensembles à une nouvelle valeur , qui est alors entièrement ignoré dans spawn_ball(). Vous utilisez direction dans toute la fonction.

La solution rapide est d'utiliser la valeur de retour de left_or_right(); ou utilisez le direc global.Étant donné que fonctionne soit sur globals, il n'y a pas de point en passant direc ici:

int_choice = 1 
spawn_ball() # don't pass anything in 

et

def spawn_ball(): 
    direction = left_or_right() 

Cependant, la meilleure façon est de toujours passe dans une direction, et supprimer complètement la (double) globaux.

Il suffit de passer dans un certain nombre, vous pouvez donner ce nombre des noms symboliques:

LEFT, RIGHT = 0, 1 # symbolic names for direction 

def spawn_ball(direction): 
    ball_pos = [WIDTH/2, HEIGHT/2] 
    if direction == LEFT: # using the global symbolic name 
     return ball_pos, [ 
      random.randrange(12, 25)*(-0.1), 
      random.randrange(6, 19)*(-0.1)] 
    else: # naturally the other option is going to be RIGHT 
     return ball_pos, [ 
      random.randrange(12, 25)*(0.1) 
      random.randrange(6, 19)*(-0.1)] 

Notez que la fonction rendement nouvelles positions à billes et la vitesse; stocker le résultat lorsque vous appelez la fonction:

ball_pos, ball_vel = spawn_ball(direction) 

Peut-être la fonction draw traite toujours ces derniers comme globals, mais ce n'est plus une préoccupation pour la fonction spawn_ball() à tout le moins.

Maintenant, tout ce que vous devez faire est de définir une variables locale soit LEFT ou RIGHT pour frayer une balle et passer cette variable dans la fonction.

1

Votre problème existe parce que vous mettez à jour au mauvais moment la variable dans votre code. Regardons un exemple de ce qui se passe après la fin d'une partie.

int_choice = 0 
spawn_ball(direc) 

Vous définissez int_choice à 0, vous appelez spawn_ball (direc), mais direc est le vieux direction - il n'a pas encore changé, que int_choice a. Alors maintenant direc a été lié à la variable "direction" dans votre fonction spawn_ball. Même si spawn_ball appelle immédiatement left_or_right(), ne mettra à jour que le direc, et non la direction, ce qui signifie que spawn_ball continuera dans la même direction qu'à l'origine, quel que soit l'appel à left_or_right.

La solution rapide serait de dire

def spawn_ball(direction): 
    direction = left_or_right() 

qui va probablement résoudre ce problème. Cependant, je vous suggère de refactoriser votre code un peu - c'est un très mauvais style. Passer des variables globales comme vous êtes est tellement sujet à des erreurs comme celle-ci - l'utilisation de locales transmises par des appels de fonctions est une bien meilleure option.