Mark.S
Mark.S

Reputation: 165

Python global variables interfering?

so basically this is a part of a little string game I am making, this is really buzzing me out. a player can press "a" or "d" to look left or right in a room to gather clues. if the player has already looked in that place. it pops a message saying "you have already been here"

although, it will go to the correct point once, then the next point will just pop a message saying "you have already been here". example. if i press "a" then "d" for "d" it will say i've already been there but i haven't. any help/suggestions??

left = 0
right = 0
#Room 1 movements
def roomOneLeft():
    global left
    left = 1
    print '-- You search the rubble and find some cloth'
    return roomOneMoves()

def roomOneRight():
    global right
    right = 1
    print '-- You find a pick under a wooden chair'
    return roomOneMoves()

#room 1 user choose
def roomOneMoves():
    global left
    global right
    move = raw_input("")
    if left == 1:
        print 'you have already been here'
        return roomOneMoves()
    if right == 1:
        print 'you have already been here'
        return roomOneMoves() 
    if move == 'a':
        roomOneLeft()     
    if move == 'd':
        roomOneRight()

roomOneMoves()

edit: Thank you all for your help. I am sorry if my code is quite frustrating to look at! got it working now. but only from your help.

Upvotes: 0

Views: 126

Answers (4)

Logan Capaldo
Logan Capaldo

Reputation: 40336

Walk through the code:

  1. We call roomOneMoves()
  2. User presses a, move becomes 'a'
  3. left is not 1, so we don't enter that branch of the if.
  4. right is not 1 so we don't enter that branch of the if.
  5. move is 'a' so we call roomOneLeft()
  6. left becomes 1, we print a message, and call roomOneMoves() again.
  7. The user presses d, move becomes 'd'
  8. left is now 1, so we print a message and call roomOneMoves() again.

In other words, you're checking if you've been to a room and bailing out, before you decide which room the user actually wants to go to.

Upvotes: 2

phihag
phihag

Reputation: 287755

You don't check your move until it's too late. Observe:

move = raw_input("")
if left == 1:
    print 'you have already been here'
    return roomOneMoves()
if right == 1:
    print 'you have already been here'
    return roomOneMoves() 
if move == 'a':
    roomOneLeft()     
if move == 'd':
    roomOneRight()

You only want to evaluate the left == 1 part if the user actually goes left, don't you? So instead, nest the if statements, like this:

move = raw_input("")
if move == 'a':
    if left:
        print 'you have already been here'
        return roomOneMoves()
    roomOneLeft()
if move == 'd':
    if right:
        print 'you have already been here'
        return roomOneMoves() 
    roomOneRight()

Also, you should rethink your data structure, and use a dictionary with boolean values or similar instead of global variables. Additionally, since most Python interpreters cannot evaluate tail recursion efficiently, you may want to use an iterative main loop instead of recursively calling the next functions.

Upvotes: 1

poke
poke

Reputation: 387537

The problem lies in your roomOneMoves function:

move = raw_input("")

First you get the direction from the user; you don’t evaluate it yet though.

if left == 1:
    print 'you have already been here'
    return roomOneMoves()
if right == 1:
    print 'you have already been here'
    return roomOneMoves() 

You check if the user has ever gone left or right before and show the message, and even worse, you start the roomOneMoves over again.

if move == 'a':
    roomOneLeft()     
if move == 'd':
    roomOneRight()

Only after that, you actually evaluate the new direction.

You should first evaluate the new direction and only when evaluating check if the direction was entered once before:

move = raw_input("")
if move == 'a':
    if left == 1:
        print 'you have already been here'
    else:
        roomOneLeft()
elif move == 'd':
    if right == 1:
        print 'you have already been here'
    else:
        roomOneRight()
roomOneMoves()

Also, you probably want to restart the method unconditionally at the end.

Upvotes: 0

akaIDIOT
akaIDIOT

Reputation: 9231

Although there are plenty of things one could say are 'iffy' about your code, your issues comes from the fact that both left and right are checked regardless of the move the player makes. If you press 'a' left becomes 1. Pressing 'd' after it will check for left being 1 and print the message.

Upvotes: 3

Related Questions