I’m trying to create a simple Game of Life by storing Cell objects into a set (have to use classes) and I reach the problem in which I cannot add the cell object into the Set because it is unhashable… is there any way around this? Thanks!
class Cell():
def __init__(self, row, col):
self.row = row
self.col = col
def getRow(self):
return self.row
def getCol(self):
return self.col
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.__dict__ == other.__dict__
else:
return False
def __ne__(self, other):
return not self.__eq__(other)
class SparseLifeGrid(set):
# Creates a new infinite-sized game grid with all cells set to dead.
def __init__(self):
self.rowList = []
self.colList = []
self.cellSet = set()
def __add__(self, cell):
self.cellSet.add(cell)
self.rowList.append(cell.getRow())
self.colList.append(cell.getCol())
def minRange(self):
#Returns a 2-tuple (minrow, mincol) that contains the minimum
#row index and the minimum
#column index that is currently occupied by a live cell.
#None is returned if there are no alive cells.
return (sorted(self.rowList)[0], sorted(self.rowList)[0])
def maxRange(self):
#Returns a 2-tuple (maxrow, maxcol) that contains the
#maximum row index and the maximum
#column index that is currently occupied by a live cell.
#None is returned if there are no live cells.
return (sorted(self.rowList,reverse = True)[0],\
sorted(self.colList,reverse = True)[0])
def clearCell(self, row, col):
#Clears the individual cell (row, col) and sets it to dead.
#If the cell is already dead, no action is taken.
for item in self:
if item == Cell(row,col):
self.remove(item)
def setCell(self, row, col):
#Sets the indicated cell (row, col) to be alive.
#If the cell is already alive, no action is taken.
self.__add__(Cell(row,col))
def isLiveCell(self, row, col):
#Returns a boolean value indicating if the given
#cell (row, col) contains a live organism.
return Cell(row,col) in self
def numLiveNeighbors(self, row, col):
#checks how many live adjacents (not diagonals I think) a cell has
surround = 0
if self.isLiveCell(row+1,col):
surround += 1
if self.isLiveCell(row-1,col):
surround += 1
if self.isLiveCell(row, col+1):
surround += 1
if self.isLiveCell(row, col-1):
surround += 1
return surround
G = SparseLifeGrid()
G.setCell(2,3)
You need to make your Cell instances immutable, then create a
__hash__method that always remains the same. If you can’t use tuples directly, here’s an alternative (that borrows only a little fromtuple):This is rather a lot of work though, for something that is equivalent to:
Your grid class also has some issues. For instance, you’re overriding
__add__, which is used for implementing the addition operator, but you don’t return anything, so it won’t work like it would be expected to. I suspect you mean to be overriding theaddmethod (with no underscores) instead. However, if that’s the case, you’ll want to be sure you callsuper().add()with appropriate arguments if you want your grid to actually function as a set.Also,
min(lst)should be much faster thansorted(lst)[0](O(N) rather than O(N log N)).