Python - 康威人生游戏
Python - Conways Game of life
我的过程似乎不适用于下一次迭代。我在 main 中有深层副本,我认为问题在于它们以及它们何时被调用。
间距有点小,抱歉。
问题出在我的结果中,它用活细胞打印了第一次迭代。然后下一次迭代是空白的,单元格没有变化。
LIVING_CELL = 'A'
DEAD_CELL = '.'
#Get the alive cells from the user
def getBoard(rows, cols, boardList):
myList = [[0]*cols for i in range(rows)]
while True:
aliveRows = input("Please enter a row of a cell to turn on (or q to exit): ")
if aliveRows == 'q':
break
aliveCols = input("Please enter a column for that cell: ")
print()
myList[int(aliveRows)][int(aliveCols)] = 1
return myList
#next board cells
def getNxtIter(cols, rows, cur, nxt):
for i in range(1,rows-1):
for j in range(1,cols-1):
nxt[i][j] = getNeighbors(i, j, cur)
#Processing the neighbor cells
def getNeighbors(x, y, boardList):
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
if boardList[i][j] != -1:
nCount += boardList[i][j]
if boardList[x][y] == 1 and nCount < 2:
return 0
if boardList[x][y] == 1 and nCount > 3:
return 1
else:
return boardList[x][y]
#Printing and forming the actual board
def printBoard(cols, rows, boardList):
for i in range(rows+2):
for j in range(cols+2):
if boardList[i][j] == -1:
print(DEAD_CELL, end=" ")
elif boardList[i][j] == 1:
print(LIVING_CELL, end=" ")
else:
print(DEAD_CELL, end=" ")
print()
def main():
#Getting and validating the number of rows and columns
x = 1
while x ==1:
rows = int(input("Please enter the number of rows: "))
if rows < 0:
x = 1
elif rows> 50:
x = 1
else:
x =0
n = 1
while n == 1:
cols = int(input("Please enter the number of columns: "))
if cols < 0:
n = 1
elif cols > 50:
n = 1
else:
n = 0
boardList = []
newBoardList = []
boardList = getBoard(rows, cols, boardList)
newBoardList = [x[:] for x in boardList]
print()
#Getting iterations to run, and validating if <= 0
a = 1
while a == 1:
iterations = int(input("How many iterations should I run? "))+1
if iterations <= 0:
a = 1
else:
a = 0
for count in range(iterations):
print()
print("Iteration:", count)
print()
printBoard(cols, rows, boardList)
getNxtIter(cols, rows, boardList, newBoardList)
boardList = [x[:] for x in newBoardList]
newBoardList = [x[:] for x in boardList]
main()
你的代码对我来说是崩溃的,因为你在 printBoard()
中的列表末尾之外进行索引。这可以通过更改范围来解决:
def printBoard(cols, rows, boardList):
for i in range(rows):
for j in range(cols):
...
可能通过清理缩进修复了其他错误,现在似乎至少在每次迭代中应用更改。
您应该对 rows, cols
参数的传递顺序保持一致,以免您以后头疼。
你在 getNeighbours()
中的 Conway 算法对我来说不正确。活细胞应该死亡,除非它们有 2 或 3 个邻居,而有 3 个邻居的死细胞应该活过来。以下更简单并且可以正常工作:
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
另一个问题是,由于 getNxtIter()
中的范围,您不会沿着板的边缘处理单元格。以下是制作董事会所需的更改 'wrap around':
#next board cells
def getNxtIter(cols, rows, cur, nxt):
for i in range(rows):
for j in range(cols):
nxt[i][j] = getNeighbors(i, j, cur)
#Processing the neighbor cells
def getNeighbors(x, y, boardList):
rows, cols = len(boardList), len(boardList[0])
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
itest, jtest = i, j
if itest == rows:
itest = 0
if jtest == cols:
jtest = 0
nCount += boardList[itest][jtest]
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
由于您似乎在应用其他答案的多项更改时遇到问题,这里有一个简化和清理的版本,我已经测试过并且在 Python 3:
中确实有效
LIVING_CELL = 'A'
DEAD_CELL = '.'
#Get the alive cells from the user
def getBoard(rows, cols):
myList = [[0]*cols for i in range(rows)]
while True:
raw = input('Please enter "row <space> column", of a cell to turn on (RETURN to exit): ')
if raw == '':
break
splitted = raw.split()
if len(splitted) != 2:
print("Invalid input")
else:
row, col = int(splitted[0]), int(splitted[1])
if row >= rows or col >= cols:
print("Invalid row/column value")
else:
myList[row][col] = 1
printBoard(rows, cols, myList)
return myList
#next board cells
def getNxtIter(rows, cols, cur, nxt):
for i in range(rows):
for j in range(cols):
nxt[i][j] = getNeighbors(rows, cols, i, j, cur)
#Processing the neighbor cells
def getNeighbors(rows, cols, x, y, boardList):
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
itest, jtest = i, j
if itest == rows:
itest = 0
if jtest == cols:
jtest = 0
nCount += boardList[itest][jtest]
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
#Printing and forming the actual board
def printBoard(rows, cols, boardList):
for i in range(rows):
line = []
for j in range(cols):
if boardList[i][j] == 1:
line.append(LIVING_CELL)
else:
line.append(DEAD_CELL)
print("".join(line))
def main():
#Getting and validating the number of rows and columns
while True:
rows = int(input("Please enter the number of rows: "))
if rows > 0 and rows <= 50:
break
while True:
cols = int(input("Please enter the number of columns: "))
if rows > 0 and rows <= 50:
break
boardList = getBoard(rows, cols)
newBoardList = [x[:] for x in boardList]
print()
#Getting iterations to run, and validating if <= 0
while True:
iterations = int(input("How many iterations should I run? "))+1
if iterations > 0:
break
for count in range(iterations):
print()
print("Iteration:", count)
print()
printBoard(rows, cols, boardList)
getNxtIter(rows, cols, boardList, newBoardList)
boardList, newBoardList = newBoardList, boardList
main()
我也改进了打印代码的性能,它在大板子上变得很慢。
我通过 firing a Glider at a Blinker on a 20x20 board 测试过,似乎工作正常。
我的过程似乎不适用于下一次迭代。我在 main 中有深层副本,我认为问题在于它们以及它们何时被调用。
间距有点小,抱歉。
问题出在我的结果中,它用活细胞打印了第一次迭代。然后下一次迭代是空白的,单元格没有变化。
LIVING_CELL = 'A'
DEAD_CELL = '.'
#Get the alive cells from the user
def getBoard(rows, cols, boardList):
myList = [[0]*cols for i in range(rows)]
while True:
aliveRows = input("Please enter a row of a cell to turn on (or q to exit): ")
if aliveRows == 'q':
break
aliveCols = input("Please enter a column for that cell: ")
print()
myList[int(aliveRows)][int(aliveCols)] = 1
return myList
#next board cells
def getNxtIter(cols, rows, cur, nxt):
for i in range(1,rows-1):
for j in range(1,cols-1):
nxt[i][j] = getNeighbors(i, j, cur)
#Processing the neighbor cells
def getNeighbors(x, y, boardList):
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
if boardList[i][j] != -1:
nCount += boardList[i][j]
if boardList[x][y] == 1 and nCount < 2:
return 0
if boardList[x][y] == 1 and nCount > 3:
return 1
else:
return boardList[x][y]
#Printing and forming the actual board
def printBoard(cols, rows, boardList):
for i in range(rows+2):
for j in range(cols+2):
if boardList[i][j] == -1:
print(DEAD_CELL, end=" ")
elif boardList[i][j] == 1:
print(LIVING_CELL, end=" ")
else:
print(DEAD_CELL, end=" ")
print()
def main():
#Getting and validating the number of rows and columns
x = 1
while x ==1:
rows = int(input("Please enter the number of rows: "))
if rows < 0:
x = 1
elif rows> 50:
x = 1
else:
x =0
n = 1
while n == 1:
cols = int(input("Please enter the number of columns: "))
if cols < 0:
n = 1
elif cols > 50:
n = 1
else:
n = 0
boardList = []
newBoardList = []
boardList = getBoard(rows, cols, boardList)
newBoardList = [x[:] for x in boardList]
print()
#Getting iterations to run, and validating if <= 0
a = 1
while a == 1:
iterations = int(input("How many iterations should I run? "))+1
if iterations <= 0:
a = 1
else:
a = 0
for count in range(iterations):
print()
print("Iteration:", count)
print()
printBoard(cols, rows, boardList)
getNxtIter(cols, rows, boardList, newBoardList)
boardList = [x[:] for x in newBoardList]
newBoardList = [x[:] for x in boardList]
main()
你的代码对我来说是崩溃的,因为你在 printBoard()
中的列表末尾之外进行索引。这可以通过更改范围来解决:
def printBoard(cols, rows, boardList):
for i in range(rows):
for j in range(cols):
...
可能通过清理缩进修复了其他错误,现在似乎至少在每次迭代中应用更改。
您应该对 rows, cols
参数的传递顺序保持一致,以免您以后头疼。
你在 getNeighbours()
中的 Conway 算法对我来说不正确。活细胞应该死亡,除非它们有 2 或 3 个邻居,而有 3 个邻居的死细胞应该活过来。以下更简单并且可以正常工作:
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
另一个问题是,由于 getNxtIter()
中的范围,您不会沿着板的边缘处理单元格。以下是制作董事会所需的更改 'wrap around':
#next board cells
def getNxtIter(cols, rows, cur, nxt):
for i in range(rows):
for j in range(cols):
nxt[i][j] = getNeighbors(i, j, cur)
#Processing the neighbor cells
def getNeighbors(x, y, boardList):
rows, cols = len(boardList), len(boardList[0])
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
itest, jtest = i, j
if itest == rows:
itest = 0
if jtest == cols:
jtest = 0
nCount += boardList[itest][jtest]
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
由于您似乎在应用其他答案的多项更改时遇到问题,这里有一个简化和清理的版本,我已经测试过并且在 Python 3:
中确实有效LIVING_CELL = 'A'
DEAD_CELL = '.'
#Get the alive cells from the user
def getBoard(rows, cols):
myList = [[0]*cols for i in range(rows)]
while True:
raw = input('Please enter "row <space> column", of a cell to turn on (RETURN to exit): ')
if raw == '':
break
splitted = raw.split()
if len(splitted) != 2:
print("Invalid input")
else:
row, col = int(splitted[0]), int(splitted[1])
if row >= rows or col >= cols:
print("Invalid row/column value")
else:
myList[row][col] = 1
printBoard(rows, cols, myList)
return myList
#next board cells
def getNxtIter(rows, cols, cur, nxt):
for i in range(rows):
for j in range(cols):
nxt[i][j] = getNeighbors(rows, cols, i, j, cur)
#Processing the neighbor cells
def getNeighbors(rows, cols, x, y, boardList):
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
itest, jtest = i, j
if itest == rows:
itest = 0
if jtest == cols:
jtest = 0
nCount += boardList[itest][jtest]
if nCount == 3 or (boardList[x][y] == 1 and nCount == 2):
return 1
return 0
#Printing and forming the actual board
def printBoard(rows, cols, boardList):
for i in range(rows):
line = []
for j in range(cols):
if boardList[i][j] == 1:
line.append(LIVING_CELL)
else:
line.append(DEAD_CELL)
print("".join(line))
def main():
#Getting and validating the number of rows and columns
while True:
rows = int(input("Please enter the number of rows: "))
if rows > 0 and rows <= 50:
break
while True:
cols = int(input("Please enter the number of columns: "))
if rows > 0 and rows <= 50:
break
boardList = getBoard(rows, cols)
newBoardList = [x[:] for x in boardList]
print()
#Getting iterations to run, and validating if <= 0
while True:
iterations = int(input("How many iterations should I run? "))+1
if iterations > 0:
break
for count in range(iterations):
print()
print("Iteration:", count)
print()
printBoard(rows, cols, boardList)
getNxtIter(rows, cols, boardList, newBoardList)
boardList, newBoardList = newBoardList, boardList
main()
我也改进了打印代码的性能,它在大板子上变得很慢。
我通过 firing a Glider at a Blinker on a 20x20 board 测试过,似乎工作正常。