2

I am making a tank game and I have tank and bullet objects. When I fire, following method is executed:

def newshot(self,tank):
    shot = bullet()
    shot.loc = tank.loc
    shot.speed = tank.direction
    self.shots.append(shot)

loc is a list that show the location [x,y], speed and direction are lists that show the speed [dx,dy].

To move each of the bullets speed vector was added to its location in a for loop. But whenever I changed the location of the bullet, the location of my tank also changed (I printed out a tanks location before and after the for loop). What I did that solved my problem was that instead of doing

shot.loc = tank.loc

I did

shot.loc = [tank.loc[0],tank.loc[1]]

My question is where is the difference?

Julius Naeumann
  • 422
  • 1
  • 10
  • 19

3 Answers3

2

You copied the reference instead of the value, which meant the two variables were pointing at the same object.

From https://docs.python.org/2/library/copy.html:

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

The simplest way to copy the tank.loc list into shot.loc is to slice the whole list:

shot.loc = tank.loc[:]

But see https://stackoverflow.com/a/2612815/768176 for other valid suggestions.

Community
  • 1
  • 1
ckhan
  • 4,771
  • 24
  • 26
1

When you use:

shot.loc = tank.loc

shot.loc and tank.loc are references to the same list.

To copy the list, use:

shot.loc = tank.loc[:]
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

You need to deepcopy the list. ie:

import copy
shot.loc = copy.deepcopy(tank.loc)

here is a how it works:

a = [[1, 2, 3], [4, 5, 6]]
b = a
a[0][1] = 10
print a
# [[1, 10, 3], [4, 5, 6]]
print b   # b changes too -> Not a deepcopy.
# [[1, 10, 3], [4, 5, 6]]


import copy
b = copy.deepcopy(a)
a[0][1] = 9
print a
#[[1, 9, 3], [4, 5, 6]]
print b    # b doesn't change -> Deep Copy
#[[1, 10, 3], [4, 5, 6]]
suhailvs
  • 20,182
  • 14
  • 100
  • 98