Hello and thank you for checking out this question. I, for a basic tile based game I am making, made my own container class that holds a matrix of items / values that represent a map in the world. To do this I learned how about operator overloading. For the most part, everything seems okay, but I am getting some results that are confusing to me.
class mapArray(object):
def __init__(self, mapdata = None, (width,height) = None, fillnumber = 0):
#If you are already given a map array, then you can just provide
# that first, otherwise leave it as none. Fill number is used to change the entire
# map array so that the map will be a different tile type. 0 is most likely just grass.
print "horses"
if (mapdata == None) and (width, height) == None:
self.mapdata = []
elif mapdata is not None:
self.mapdata = mapdata
elif (width,height) is not None:
self.mapdata = [[fillnumber] * width] * height
def __setitem__(self, (x,y), value):
#Allows you to assign values more intuitively with the array
self.mapdata[y][x] = value
def __getitem__(self, (x,y)):
#Just reverses it so it works intuitively and the array is
# indexed simply like map[x,y] instead of map[y][x]
return mapArray(self.mapdata[y][x])
def __str__(self):
return str(self.mapdata)
def __repr__(self):
return str(self.mapdata)
def __len__(self):
return len(self.mapdata)
The getitem works fine. I have the constructor set to either take in a given list of lists, or provide a length and width that just makes an array of that size. Here are the results I get when I provide a size for the array, as opposed to giving it my own values.
testlist1 = mapArray(None, (3,3), 4)
print testlist1
testlist1[0,1] = 5
print testlist1
This gives me these results:
[[4,4,4],[4,4,4],[4,4,4]]
[[5,4,4],[5,4,4],[5,4,4]]
The first result makes sense, but the second result seems to show a problem in my setitem method that I overrode. Why does it replace the first index of every list?
And also confusing to me is what happens when I provide my own list of lists to replace the mapdata argument.
randommap = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
testlist2 = mapArray(randommap)
print testlist2
That code gives me this TypeError:
def __init__(self, mapdata = None, (width,height) = None, fillnumber = 0):
TypeError: 'NoneType' object is not iterable
to me this seems like it is saying that the mapdata is not iterable when it is set to None, but shouldnt the randommap lists I provide replace the mapdata? Perhaps there is a problem with the conditional statements I have setup so that it never gets replaced. I can’t seem to narrow down what the issue is. Any help would be greatly appreciated!
I am new to operator overloading so if there are any more efficient ways to do this let me know. I know that numpy exists to do most of this for me but I wanted to do this on my own.
Thanks again!
Ryan
The problem is in
__init__(). Specifically this line:This creates
heightreferences to the same list. The fix is: