python - Conway 的生命游戏在计算邻居时出现错误,因此得到错误的结果
python - Conway's Game of Life bug at calculating neighbors, and therefore gets wrong results
我正在尝试构建“Conway 的生命游戏”,但出于某种原因,邻居的数量计算不正确,因此我得到了错误的结果。请帮助我:)
我很迷茫我不知道怎么了...
我试过的例子,只是让白板空白
[[1, 1, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 1], [1, 1, 0, 1 , 1], [0, 1, 0, 1, 0]]
| * | * | | | |
| | * | * | * | |
| | | | * | * |
| * | * | | * | * |
| | * | | * | |
def userinp(size_):
"""
create the matrix by taking user input on board with user default range size.
:return: a matrix (lists inside a list)
"""
matrix = []
for i in range(size_):
line = []
for j in range(size_):
cell = int(input(f"Row {i + 1} column {j + 1} : "))
line.append(cell)
matrix.append(line)
if i == size_ - 1: # when reach limit of rows & lines we stop asking from the user an input.
continue
else:
print(f"line {i+1} submitted. continue to line {i+2} : ")
return matrix
def draw(board, size):
"""
draw the board by user input (board) of matrix and games rules.
"""
for i in range(size):
print(" ---" * size)
for j in range(size):
if board[i][j] == 0:
print("| ", end='')
elif board[i][j] == 1:
print("| * ", end='')
if j == size - 1:
print("|")
if i == size - 1:
print(" ---" * size)
def calc_cell(old_status, size, matrix, row, col, new_status=0, neighbors=0):
"""
calculate neighbors and return the new value of the cell.
:param old_status: boolean value represent if the cell alive or dead
:param new_status: the new value that will be returned to the cell
:param size: size of matrix
:param matrix: the data of the matrix
:param row: the row of the cell The function check
:param col: the column of the cell the function check
:param neighbors: number of the live neighbors of the cell.
:return: '1' if alive or '0' if dead.
"""
# check all the cells around the cell, before checking the cells I check if the neighbor cell is in our range.
if row - 1 >= 0 and col - 1 >= 0:
if matrix[row-1][col-1] == 1:
neighbors += 1
elif row - 1 >= 0:
if matrix[row-1][col] == 1:
neighbors += 1
elif row - 1 >= 0 and col + 1 < size:
if matrix[row-1][col+1] == 1:
neighbors += 1
elif col - 1 >= 0:
if matrix[row][col-1] == 1:
neighbors += 1
elif col + 1 < size:
if matrix[row][col+1] == 1:
neighbors += 1
elif col - 1 >= 0 and row + 1 < size:
if matrix[row+1][col-1] == 1:
neighbors += 1
elif row + 1 < size:
if matrix[row+1][col] == 1:
neighbors += 1
elif col + 1 < size and row + 1 < size:
if matrix[row+1][col+1] == 1:
neighbors += 1
print(f"neighbors = {neighbors}") # todo: delete
# check by the rules of the game what is the new status of the cell.
alive = old_status
if alive and neighbors <= 1:
new_status = 0
elif neighbors > 3:
new_status = 0
elif not alive and neighbors == 3:
new_status = 1
elif alive and (neighbors == 2 or neighbors == 3):
new_status = int(old_status) # convert the boolean value to '0' or '1' (integers)
return new_status
def main():
s = int(input("Please enter the size of the board (rows = columns): "))
print("Please enter input for stating the game.\nInput is '1' for a live cell and
'0' for dead cell.")
b = userinp(s) # my board, a matrix.
draw(b, s)
# start checking cells status
while True:
# create empty matrix to store updated values
line = [0 for _ in range(s)]
new_mat = [line for _ in range(s)]
# put new values in new matrix
for row in range(s):
for col in range(s):
new_mat[row][col] = calc_cell(old_status=bool(b[row][col]), size=s, matrix=b, row=row, col=col)
print(b) # todo: delete
draw(new_mat, s)
q = input("would you like the program to continue calculating the board? (type yes / no): ").lower()
if 'n' in q:
break
else:
b = new_mat
if __name__ == '__main__':
main()
在if
和elif
的系列中,最多执行其中一个,这意味着neighbors
是0或1。
您可以将 elif
s 替换为 if
s,但我建议至少使用一些循环来简化代码:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
# For the 3x3 square around the cell
if (0 <= col + dx < size) and (0 <= row + dy < size):
if (dx != 0 or dy != 0) and matrix[row + dy][col + dx] == 1:
# Excludes the cell itself
neighbors += 1
您的代码中还有另一个错误:
line = [0 for _ in range(s)]
new_mat = [line for _ in range(s)]
现在new_mat
是一个条目列表,所有条目都指向同一行,这意味着修改一行将有效地修改所有行。相反,使用:
new_mat = [[0 for _ in range(s)] for _ in range(s)]
我正在尝试构建“Conway 的生命游戏”,但出于某种原因,邻居的数量计算不正确,因此我得到了错误的结果。请帮助我:)
我很迷茫我不知道怎么了...
我试过的例子,只是让白板空白
[[1, 1, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 1], [1, 1, 0, 1 , 1], [0, 1, 0, 1, 0]]
| * | * | | | |
| | * | * | * | |
| | | | * | * |
| * | * | | * | * |
| | * | | * | |
def userinp(size_):
"""
create the matrix by taking user input on board with user default range size.
:return: a matrix (lists inside a list)
"""
matrix = []
for i in range(size_):
line = []
for j in range(size_):
cell = int(input(f"Row {i + 1} column {j + 1} : "))
line.append(cell)
matrix.append(line)
if i == size_ - 1: # when reach limit of rows & lines we stop asking from the user an input.
continue
else:
print(f"line {i+1} submitted. continue to line {i+2} : ")
return matrix
def draw(board, size):
"""
draw the board by user input (board) of matrix and games rules.
"""
for i in range(size):
print(" ---" * size)
for j in range(size):
if board[i][j] == 0:
print("| ", end='')
elif board[i][j] == 1:
print("| * ", end='')
if j == size - 1:
print("|")
if i == size - 1:
print(" ---" * size)
def calc_cell(old_status, size, matrix, row, col, new_status=0, neighbors=0):
"""
calculate neighbors and return the new value of the cell.
:param old_status: boolean value represent if the cell alive or dead
:param new_status: the new value that will be returned to the cell
:param size: size of matrix
:param matrix: the data of the matrix
:param row: the row of the cell The function check
:param col: the column of the cell the function check
:param neighbors: number of the live neighbors of the cell.
:return: '1' if alive or '0' if dead.
"""
# check all the cells around the cell, before checking the cells I check if the neighbor cell is in our range.
if row - 1 >= 0 and col - 1 >= 0:
if matrix[row-1][col-1] == 1:
neighbors += 1
elif row - 1 >= 0:
if matrix[row-1][col] == 1:
neighbors += 1
elif row - 1 >= 0 and col + 1 < size:
if matrix[row-1][col+1] == 1:
neighbors += 1
elif col - 1 >= 0:
if matrix[row][col-1] == 1:
neighbors += 1
elif col + 1 < size:
if matrix[row][col+1] == 1:
neighbors += 1
elif col - 1 >= 0 and row + 1 < size:
if matrix[row+1][col-1] == 1:
neighbors += 1
elif row + 1 < size:
if matrix[row+1][col] == 1:
neighbors += 1
elif col + 1 < size and row + 1 < size:
if matrix[row+1][col+1] == 1:
neighbors += 1
print(f"neighbors = {neighbors}") # todo: delete
# check by the rules of the game what is the new status of the cell.
alive = old_status
if alive and neighbors <= 1:
new_status = 0
elif neighbors > 3:
new_status = 0
elif not alive and neighbors == 3:
new_status = 1
elif alive and (neighbors == 2 or neighbors == 3):
new_status = int(old_status) # convert the boolean value to '0' or '1' (integers)
return new_status
def main():
s = int(input("Please enter the size of the board (rows = columns): "))
print("Please enter input for stating the game.\nInput is '1' for a live cell and
'0' for dead cell.")
b = userinp(s) # my board, a matrix.
draw(b, s)
# start checking cells status
while True:
# create empty matrix to store updated values
line = [0 for _ in range(s)]
new_mat = [line for _ in range(s)]
# put new values in new matrix
for row in range(s):
for col in range(s):
new_mat[row][col] = calc_cell(old_status=bool(b[row][col]), size=s, matrix=b, row=row, col=col)
print(b) # todo: delete
draw(new_mat, s)
q = input("would you like the program to continue calculating the board? (type yes / no): ").lower()
if 'n' in q:
break
else:
b = new_mat
if __name__ == '__main__':
main()
在if
和elif
的系列中,最多执行其中一个,这意味着neighbors
是0或1。
您可以将 elif
s 替换为 if
s,但我建议至少使用一些循环来简化代码:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
# For the 3x3 square around the cell
if (0 <= col + dx < size) and (0 <= row + dy < size):
if (dx != 0 or dy != 0) and matrix[row + dy][col + dx] == 1:
# Excludes the cell itself
neighbors += 1
您的代码中还有另一个错误:
line = [0 for _ in range(s)]
new_mat = [line for _ in range(s)]
现在new_mat
是一个条目列表,所有条目都指向同一行,这意味着修改一行将有效地修改所有行。相反,使用:
new_mat = [[0 for _ in range(s)] for _ in range(s)]