1

So I decided to write Monopoly in Python, but I'm having some trouble updating the players location. I wrote a for loop that iterates through the players, rolls the dice for each one, and then updates their location. The problem is that the location variable isn't keeping the latest location, it keeps resetting back to 0 at the start of the for loop. Here's my code:

player1location = 0

def turn(numberPlayers, player, player1location, Board):
    for player in range(numberPlayers):
        player = 'Player'+str(player+1)
        print 'It\'s', player, 'turn!'
        print player1location
        rollDice = raw_input('Press Enter to roll the dice!')
        diceRoll = random.randint(1,6)
        print player, 'rolled a', diceRoll
        player1location = player1location + diceRoll
        print 'You landed on', player1location
        print '\n'

while True:
    turn(numberPlayers, player, player1location, Board)

I can provide more of the code if necessary, but I think this is everything that controls the players location. Thanks!

EDIT: So apparently I'm changing the local variable instead of the global variable. How would I change the global variable instead?

Stephen Roda
  • 859
  • 6
  • 13
  • 20
  • Your call within the loop is using the global `player1location`, while inside the function you're changing a local variable that gets thrown away when you exit the scope. – Wooble Feb 13 '13 at 16:39
  • Arent you supposed to use the `global` keyword when using global variables? – gustavodidomenico Feb 13 '13 at 16:39
  • (also, why are you only tracking the location of 1 player and moving it for each player in the game?) – Wooble Feb 13 '13 at 16:40
  • So how would I change the global variable instead of the local variable? (and I'm just getting the basis for one player down first and then I'll add more later) – Stephen Roda Feb 13 '13 at 16:46
  • Although you _could_ change the global variable in the function with a `global player1location` statement in `turn()` (and removing the arugment), it would be much better to make the function return the updated value and have the caller update it. – martineau Feb 13 '13 at 17:02
  • How would I make the caller update it? – Stephen Roda Feb 13 '13 at 17:07

2 Answers2

8

You have function parameter with the same name as your target variable which you want to update. Due to which, any changes you make is made to the function parameter, and not to the global variable. That's because the function creates a local scope for the paremeter you are passing to the function. So, it overshadows the variable defined with the same name globally.

So, either change the name of the function parameter player1location or the name of the global variable.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • I don't really understand what you mean. I tried changing the name of the variables, but it's still not working. It says that the variable is both local and global. – Stephen Roda Feb 13 '13 at 16:50
  • @emagdnim. Where did you get that error? Ah! and you need to use `global lplayer1location` to use the global variable. – Rohit Jain Feb 13 '13 at 16:52
  • @emagdnim. Well, it would be even better not to use global variable at all. Just return the changes done to the local variable, and store the return value of while loop in the variable defined outside. – Rohit Jain Feb 13 '13 at 16:54
  • It's almost never good to use a global variable. It's usually a sign of bad design. – Wooble Feb 13 '13 at 17:05
  • @emagdnim Global variables are generally to be avoided because they're *too easy* - you can modify them anywhere. Because that's the case, in larger programs, it becomes difficult to trace any bugs that might be related to them. For example, if you change a global variable in a way every other function wasn't expecting, this can lead to many unforeseen errors that won't turn up until you run those particular functions. – Hannele Feb 13 '13 at 19:26
1

Note that you have two variables called player1location - one is defined globally in your first line (outside of any function): player1location = 0, and the second one is created locally each time you call your function: def turn(numberPlayers, player, player1location, Board). Even though they have the same name, these are two distinct variables in python, because they are defined in different scopes.

There are a couple of ways you could fix this.

You could remove player1location from your function definition, and then you'd always be changing the globally-scoped variable. However, from your naming convention, I'm guessing that you'd like to reuse the function for other players as well (although it still couldn't hurt to try it, to help you understand how it works).

The better way would likely be to return the new player location at the end of your function (return player1location), and then assign it to the globally-scoped location upon return (player1location = turn(numberPlayers, player, player1location, Board)).

Hannele
  • 9,301
  • 6
  • 48
  • 68
  • What do you mean "You could remove player1location from your function definition?" – Stephen Roda Feb 13 '13 at 16:54
  • Like this: `def turn(numberPlayers, player, Board)`. Then, you call your function like this: `turn(numberPlayers, player, Board)`. Python should then be able to pick up `player1location` from the global scope. – Hannele Feb 13 '13 at 16:55