蟒蛇 - 康威的生命游戏 - 不会更新到下一个周期



我是python的新手,来自Java和C#。我有一个Java的工作实现,但当我尝试用Python编写它时,网格不会更新到下一个周期。我认为问题不在于深度复制。可能是数组元素的重新分配吗?

import copy
liveSymbol = "X"
deadSymbol = "-"
class Cell:
    def __init__(self, live, symbol, row, column):
        self.live = live
        self.symbol = symbol
        self.row = row
        self.column = column
    def __repr__(self):
        return repr(self.symbol)
class Model:
    def __init__(self, rows, columns):
        self.grid = []
        self.nextGrid = []
        self.rows = rows
        self.columns = columns
        self.initGrids()
        self.addPatternToGrid()
    def initGrids(self):
        for i in range(self.rows):
            self.grid.append([])
            self.nextGrid.append([])
            for j in range(self.columns):
                cell = Cell(False, deadSymbol, i, j)
                self.grid[i].append(cell)
                self.nextGrid[i].append(cell)
    def addPatternToGrid(self):
        self.grid[1][2] = Cell(True, liveSymbol, 1, 2)
        self.grid[2][2] = Cell(True, liveSymbol, 2, 2)
        self.grid[3][2] = Cell(True, liveSymbol, 3, 2)
    def printGrid(self):
        print("GRID")
        print("n______________________", end=" ")
        for i in range(self.rows):
            print("")
            for j in range(self.columns):
                print(self.grid[i][j], end=" ")
    def printNextGrid(self):
        print("Next Grid")
        print("n______________________", end=" ")
        for i in range(self.rows):
            print("")
            for j in range(self.columns):
                print(self.grid[i][j], end=" ")
    def start(self):
        for i in range(self.rows):
            for j in range(self.columns):
                willLive = self.aliveNextCycle(self.grid[i][j])
                symbol = self.getSymbol(willLive)
                self.nextGrid[i][j] = Cell(willLive, symbol, i, j)
        print("Before update grid to next cycle")
        self.printGrid()
        self.printNextGrid()
        self.updateGridToNextCycle()
        print("After update grid to next cycle")
        self.printGrid()
        self.printNextGrid()
    def getSymbol(self, isLive):
        return liveSymbol if True else deadSymbol
    def aliveNextCycle(self, cell):
        liveNeighbors = self.countTheLiveNeighbors(cell)
        if cell.live:
            live = not (liveNeighbors < 2 or liveNeighbors > 3)
            return not live
        else:
            lives = liveNeighbors==3
            return lives
    def updateGridToNextCycle(self):
        # for i in range(self.rows):
        #     for j in range(self.columns):
        #         self.grid[i][j] = self.nextGrid[i][j]
        self.grid = copy.deepcopy(self.nextGrid)
    def countTheLiveNeighbors(self, cell):
        count = 0
        # Directly Left
        if cell.column != 0:
            if self.grid[cell.row][cell.column - 1].live:
                count += 1
            # Upper Left
        if cell.row != 0 and cell.column != 0:
            if self.grid[cell.row - 1][cell.column - 1].live:
                count += 1
            # Directly above
        if cell.row != 0:
            if self.grid[cell.row - 1][cell.column].live:
                count += 1
            # Above right
        if cell.row != 0 and cell.column != self.columns - 1:
            if self.grid[cell.row - 1][cell.column + 1].live:
                count += 1
            # Directly right
        if cell.column != self.columns - 1:
            if self.grid[cell.row][cell.column + 1].live:
                count += 1
            # Right under
        if cell.row != self.rows - 1 and cell.column != self.columns - 1:
            if self.grid[cell.row + 1][cell.column + 1].live:
                count += 1
            # Directly beneath
        if cell.row != self.rows - 1:
            if self.grid[cell.row + 1][cell.column].live:
                count += 1
            # Down left
        if cell.row != self.rows - 1 and cell.column != 0:
            if self.grid[cell.row + 1][cell.column - 1].live:
                count += 1
        return count
model = Model(5, 5)
model.start()

以下是输出

Before update grid to next cycle
GRID
______________________ 
'-' '-' '-' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' '-' '-' '-' Next Grid
______________________ 
'-' '-' '-' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' 'X' '-' '-' 
'-' '-' '-' '-' '-' After update grid to next cycle
GRID
______________________ 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' Next Grid
______________________ 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 
'X' 'X' 'X' 'X' 'X' 

我在这里看到了几个问题。

首先,您的printNextGrid()函数与printGrid()函数完全相同;它打印来自CCD_ 3而不是CCD_。你对copy.deepcopy的使用非常好。

其次,在Cell对象中嵌入了太多信息。每个细胞只需要跟踪自己的状态;它不需要单独存储用于其当前状态和位置的符号。(说实话,还不清楚这是否需要成为一个对象;我强烈建议您将TrueFalse存储在网格中,而不是对象。这将使您的代码更加简单。)

但至关重要的是,您对getSymbol()aliveNextCycle()的实现是不正确的。第一:

def getSymbol(self, isLive):
    return liveSymbol if True else deadSymbol
                      ^^^^^^^

True总是正确的。这里需要的条件是isLive

第二:

def aliveNextCycle(self, cell):
    liveNeighbors = self.countTheLiveNeighbors(cell)
    if cell.live:
        live = not (liveNeighbors < 2 or liveNeighbors > 3)
        return not live
    else:
        lives = liveNeighbors==3
        return lives

cell.live病例的逻辑过于复杂,最终颠倒了生存条件,导致了错误的行为。一个简单得多(正确)的实现是:

def aliveNextCycle(self, cell):
    liveNeighbors = self.countTheLiveNeighbors(cell)
    if liveNeighbors == 3: return True
    if liveNeighbors == 2: return cell.live
    return False

相关内容

最新更新