生命游戏散列Python

2024-06-11 06:33:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过将单元格对象存储到一个集合(必须使用类)来创建一个简单的生活游戏,但我遇到了一个问题:我无法将单元格对象添加到集合中,因为它是不可修复的。。。有什么办法吗?谢谢!在

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)

Tags: theselflivereturnifisdefcell
2条回答

您需要使单元实例不可变,然后创建一个始终保持不变的__hash__方法。如果您不能直接使用元组,这里有一个替代方法(只借用tuple)一点:

class Cell:
    # each cell will have exactly two values, so no need for __dict__
    __slots__ = ["row", "col"]

    # set up values at construction time using super().__setitem__()
    def __init__(self, row, col):
        super().__setitem__("row", row)
        super().__setitem__("col", col)
        return self

    # a Cell is intended to be immutable, so __setattr__ always raises an error
    def __setattr__(self, name, value):
        if hasattr(self, name):
            raise AttributeError("{!r} object attribute {!r} is read-only"
                                 .format(self.__class__.__name__, name))
        else:
            raise AttributeError("{!r} object has no attribute {!r}"
                                 .format(self.__class__.__name__, name))

    # comparison operators
    def __eq__(self, other):
        return (isinstance(other, Cell) and
                self.row == other.row and
                self.col == other.col)

    def __ne__(self, other):
        return not self == other

    # hash function, with a value borrowed from a tuple
    def __hash__(self):
        return hash((self.row, self.col))

不过,这相当于做了大量的工作:

^{pr2}$

网格类也有一些问题。例如,您重写了用于实现加法运算符的__add__,但是您没有返回任何内容,因此它不会像预期的那样工作。我怀疑您的意思是重写add方法(没有下划线)。但是,如果是这样的话,如果您希望网格实际作为一个集合来运行,那么您需要确保使用适当的参数调用super().add()。在

而且,min(lst)应该比sorted(lst)[0](O(N)而不是O(N logn))快得多。在

您的对象是可变的,并且您还没有实现__hash__();但是无论如何,您并不想实现它。你的单元格只在存在的情况下表示活动,所以只需在集合中使用一个元组(row, col)。由于元组是不可变的和散列的,所以可以将它们放入集合中。在

使用网格和游戏的类和对象,而不是单元格。在

相关问题 更多 >