Search code examples
pythoninstanceglobal

Why are my different instance variables linking together despite the .copy()?


as a novice to python, I feel like it's a lot to ask random strangers what the problem is for every measly problem but after researching, I cannot find out the problem. What I created was a 2D grid movement system using lists in a list. The end goal was for the user to walk continuously through corridors but after the first corridor, a present would continuously appear in a set location. However, the first time the user walks over the present, the present is deleted from the hardcoded art (lobby_art) that is only connected to the list that is edited (currentlocation). Below is an attempt to excavate the problem out from the code and simplify it.

lobby_art = [
    ['ā€– ', '  ', '  ā€–'],
    ['ā€– ', 'šŸŽ', '  ā€–'],
    ['ā€– ', '  ', '  ā€–'],
    ['ā€– ', 'šŸ™‚', '  ā€–'],
]

currentlocation = [
    ['ā€– ', '  ', '  ā€–'],
    ['ā€– ', '  ', '  ā€–'],
    ['ā€– ', '  ', '  ā€–'],
    ['ā€– ', 'šŸ™‚', '  ā€–'],
]

def moveup(direction):
    if direction == 'w':
        global currentlocation
        global userlocationY
        if userlocationY == 0:
            global leave_corridor 
            leave_corridor = False
            currentlocation[userlocationY][1] = '  ' #deletes previous location
            return
        currentlocation[userlocationY][1] = '  ' 

        userlocationY -= 1
        currentlocation[userlocationY][1] = 'šŸ™‚'

def lobbyprint(): #Prints Lobby layout
    global currentlocation
    for i in currentlocation: 
        print(''.join(i))

Corridor_with_present = False
GameOngoing = True  
while GameOngoing:        
    
    
    if Corridor_with_present == True:
        currentlocation = lobby_art.copy()
    
    leave_corridor = True
    userlocationY = 3
    while leave_corridor:
        lobbyprint()
        direction = input("Input w: ")
        moveup(direction)

    Corridor_with_present = True

Output

ā€–     ā€–
ā€–     ā€–
ā€–     ā€–
ā€– šŸ™‚  ā€–
Input w: w
ā€–     ā€–
ā€–     ā€–
ā€– šŸ™‚  ā€–
ā€–     ā€–
Input w: w
ā€–     ā€–
ā€– šŸ™‚  ā€–
ā€–     ā€–
ā€–     ā€–
Input w: w
ā€– šŸ™‚  ā€–
ā€–     ā€–
ā€–     ā€–
ā€–     ā€–
Input w: w
ā€–     ā€–
ā€– šŸŽ  ā€–
ā€–     ā€–
ā€– šŸ™‚  ā€–
Input w: w
ā€–     ā€–
ā€– šŸŽ  ā€–
ā€– šŸ™‚  ā€–
ā€–     ā€–
Input w: w
ā€–     ā€–
ā€– šŸ™‚  ā€–
ā€–     ā€–
ā€–     ā€–
Input w: w
ā€– šŸ™‚  ā€–
ā€–     ā€–
ā€–     ā€–
ā€–     ā€–
Input w: w
ā€–     ā€–
ā€–     ā€–
ā€–     ā€–
ā€–     ā€–
Input w: w
ā€–     ā€–
ā€–     ā€–
ā€– šŸ™‚  ā€–
ā€–     ā€–
Input w:

I have tried using .copy(), [:], even import copy on the statement but to no avail.

if Corridor_with_present == True:
        currentlocation = lobby_art.copy()

Does anyone know why?

Thanks Robert.


Solution

  • try this:

    import copy
    if Corridor_with_present == True:
            currentlocation = copy.deepcopy(lobby_art)
    

    lobby_art.copy() just copy the reference, while copy.deepcopy(lobby_art) copy the whole object in memory.

    just like the image shown below: enter image description here