-3

I have this function move() function in a class which is incorrectly adding 2 instead of 1 in a line containing self.coords[1] += 1

here's the file:

class Actor():
    def __init__(self, start, limits, barriers):
        self.coords = start
        self.limits = limits
        self.barriers = barriers
    
    def canmove(self, direction):
        moving = self.coords
        if(direction == 'up'):
            moving[1] -= 1
        elif(direction == 'right'):
            moving[0] += 1
        elif(direction == 'down'):
            moving[1] += 1
        elif(direction == 'left'):
            moving[0] -= 1
        
        if((moving[0] > self.limits[0]) or (moving[1] > self.limits[1]) or (-1 in moving) or (moving in self.barriers)):
            return False
        else:
            return True

    def move(self, direction):
        if(direction == 'up'):
            if self.canmove('up'):
                self.coords[1] -= 1
        elif(direction == 'right'):
            if self.canmove('right'):
                self.coords[0] += 1
        elif(direction == 'down'):
            if self.canmove('down'):
                self.coords[1] += 1
        elif(direction == 'left'):
            if self.canmove('left'):
                self.coords[0] -= 1

I know the canmove() function doesn't quite work yet but it doesn't interfere with the results.

When running Actor.move('up') it is decreasing Actor.coords[1] by two instead of one.

Here's what happens (even when ignoring the canmove() check):

>>> from actor import Actor
>>> actor = Actor([2, 2], [10, 5], [[4, 4]])
>>> actor.move('down')  
>>> actor.coords
[2, 4]

and actor.move(down) is supposed to increase the value of actor.coords[1] by one, not two.

1 Answers1

0

There is a weird little nuance where in your canmove function moving = self.coords does not actually copy the list, it just copies a reference to where the list is located in memory (here is an explanation for what is going on). So both moving and self.coords point to the same list, and this is causing your canmove function to move your character (and then when the move function moves the character it gets moved twice). What you want to do is:

import copy
moving = copy.deepcopy(self.coords)

And that will copy the list and all items inside of the list.


hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
  • `canmove()` checks and modifies `moving`, not `self.coords`, or does that somehow link up? – João H. L. Corrêa Jan 26 '21 at 18:52
  • @JoãoH.L.Corrêa As is already stated in the above answer; `moving = self.coords` doesn't make a copy of `self.coords`, it's a pointer to the same list. That means that when you make a change to `moving`, it's changing the same list that is in the `self.coords` variable. – Hampus Larsson Jan 26 '21 at 19:00