作为对自己的挑战,我试着写出康威的生命游戏模拟器。虽然从输入值到打印出第一代和第二代,外翻工作正常,但在处理更多代时我遇到了麻烦。
到目前为止,这是我的代码:
class Game_setup:
def __init__(self, cells):
self.boundry = 20
self.cells = cells
self.x_cord = []
self.y_cord = []
self.cord_pairs = []
self.coordinates = []
self.dead_pairs = []
def inital_values(self):
coordinates = []
for x in range(int(self.boundry)):
for y in range(int(self.boundry)):
coordinates.append([x, y])
self.coordinates = coordinates
return coordinates
def intial_cells(self):
cord_pairs = []
with open(self.cells, 'r', encoding="utf-8") as file:
for line in file:
row = line.split()
cord_pairs.append([int(row[0]),int(row[1])])
x = []
y = []
for number_of_coordinates in range(len(cord_pairs)):
x.append(cord_pairs[number_of_coordinates][0])
y.append(cord_pairs[number_of_coordinates][1])
self.x_cord = x
self.y_cord = y
self.cord_pairs = cord_pairs
return cord_pairs
def neighbours(self, n):
neighbours = 0
x_coordinate = self.cord_pairs[n][0]
y_coordinate = self.cord_pairs[n][1]
if [x_coordinate,y_coordinate+1] in self.cord_pairs:
neighbours += 1
if [x_coordinate,y_coordinate-1] in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate] in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate-1] in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate+1] in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate] in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate-1] in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate+1] in self.cord_pairs:
neighbours += 1
return neighbours
def from_dead_to_alive(self,pair):
x_coordinate = pair[0]
y_coordinate = pair[1]
neighbours = 0
if [x_coordinate,y_coordinate+1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate,y_coordinate-1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate-1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate+1,y_coordinate+1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate-1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if [x_coordinate-1,y_coordinate+1] in self.cord_pairs and [x_coordinate,y_coordinate] not in self.cord_pairs:
neighbours += 1
if neighbours == 3:
self.dead_pairs.append([x_coordinate,y_coordinate])
return neighbours
def evaluate_initial_position(self,y_coordinate): # n är y koordinaterna som itereras över
coordinates_to_print = []
if y_coordinate in self.y_cord:
x_in_y = [x_coordinate for x_coordinate, y_values in enumerate(self.y_cord) if y_values == y_coordinate]
for items in range(len(x_in_y)):
coordinates_to_print.append(self.x_cord[x_in_y[items]])
for number_of_rows in range(self.boundry):
board_rows = ''.join('X' if item in coordinates_to_print else '-' for item in list(range(self.boundry)))
return print(board_rows)
def nxt_gen_cell_status(self):
status = {}
for lenght_initial_values in range(len(life.intial_cells())):
if life.neighbours(lenght_initial_values) == 3 or life.neighbours(lenght_initial_values) == 2:
status[tuple(self.cord_pairs[lenght_initial_values])] = "Alive"
elif life.neighbours(lenght_initial_values) < 2 or life.neighbours(lenght_initial_values) > 3:
status[tuple(self.cord_pairs[lenght_initial_values])] = "Dead"
for lenght_dead_cells in range(len(self.dead_pairs)):
status[tuple(self.dead_pairs[lenght_dead_cells])] = "Alive"
return status
def new_cells(self,status):
del self.cord_pairs[:]
for alive_cell in range(len(list(status.keys()))):
kord = list(status.keys())[alive_cell]
if status[kord] == "Alive":
self.cord_pairs.append(list(kord))
return self.cord_pairs
def set_board(self):
x = []
y = []
for new_coordinate in range(len(self.cord_pairs)):
x.append(self.cord_pairs[new_coordinate][0])
y.append(self.cord_pairs[new_coordinate][1])
self.x_cord = x
self.y_cord = y
return self.cord_pairs, self.y_cord
cells = 'www.csc.kth.se/~lk/P/glidare.txt'
life = Game_setup(cells)
def main():
cell_status_ditction = {}
life.intial_cells()
generation = input("How many generations would you like to see?" + "\n")
i = 0
while i < int(generation):
for boundry in range(10):
life.evaluate_initial_position(boundry)
for next_cells in range(len(life.inital_values())):
life.from_dead_to_alive(life.inital_values()[next_cells])
cell_status = life.nxt_gen_cell_status()
cell_status_ditction.update(cell_status)
life.new_cells(cell_status_ditction)
life.set_board()
cell_status_ditction.clear()
print("\n" + "\n")
i += 1
main()
注意事项:
set_board
如果我运行这三代,那就是结果:
--------------------
---X----------------
-X-X----------------
--XX----------------
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------
--X-----------------
---XX---------------
--XX----------------
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------
--X-----------------
---XX---------------
--XX----------------
--------------------
--------------------
--------------------
--------------------
--------------------
--------------------
正如人们可以注意到第三个没有正确更新。有没有解决这个问题?我应该正确更新我的电路板吗?
有关如何修复或使代码更好的任何帮助都非常感谢。我是新手编码器所以请温柔;我知道这不是最好的也不是最优的代码。
答案 0 :(得分:0)
看起来像什么正在发生的事情是你的董事会没有得到新状态的更新。
我不知道python,所以我不会尝试逐行调试这段代码(或者自己编写python代码),但一般来说,Game of Life模拟器应该看起来像这样的东西(我已经抽出了一些抽象的东西,比如board
的底层表示,因为这些是实现细节会有所不同,并且特定于你的代码):
#definition of board.get_neighbor_count(cell)
neighbors = 0
for(row in [cell.row - 1, cell.row + 1])
for(column in [cell.column - 1, cell.column + 1])
#We skip the center cell.
if(row == 0 && column == 0) continue
#We don't want to scan cells like [-1,0] or [20,0], which would be out of
#bounds. I don't know how python handles OOB accesses, but I imagine the program
#would crash instead of behaving gracefully
if(!board.in_bounds(row, column)) continue
if(board.get_cell(row, column).alive) neighbors++
return neighbors
#==============================================================
#definition of board.get_next_generation()
Game_Board new_board(rows = board.rows, columns = board.columns, ruleset = board.ruleset)
for(row in [0, board.rows-1])
for(column in [0, board.columns-1])
cell = board.get_cell(row, column)
neighbors = board.get_neighbor_count(cell)
if(cell.alive && board.ruleset.survives(neighbors))
new_board.put(cell)
else if(cell.dead && board.ruleset.births(neighbors))
new_board.put(cell)
return new_board
#==============================================================
#definition of main()
#Should create an empty board size 20x20. I'm assuming they'll be addressed
#[0...rows-1],[0...columns-1]
Game_Board board{rows = 20, columns = 20, ruleset = 23S/3B}
#I'm putting values here for a Gosper Glider, but if your implementation is correct
#one could put literally anything here
board.put_starting_values({10,10}, {10,11}, {10,12}, {11,12}, {12,11})
board.print_state()
num_of_generations = 50
while(num_of_generations > 0)
#Note that I'm assigning a new value to `board` here! This is deliberate and
#intended to convey explicit semantics, in that `board` should now refer to the
#newly generated state, not the preexisting state. If, for whatever reason,
#you need to maintain the original state, either store each successive generation
#in an array or just the original state in a separate variable.
board = board.get_next_generation()
board.print_state()
num_of_generations--
print("Done!")
你需要做的是将你的main()
减少到这个逻辑流程,并找出错误的位置,因为这是一个完整的逻辑(非常简单) )GOL模拟器。以我写的方式写它应该使错误非常明显。就目前而言,你的代码包含很多内容,其中from_dead_to_alive
等函数试图复制neighbors
所做的工作(函数本身过于复杂)。同时,您已经拥有一个名为status
的完整独立实体,负责跟踪这些单元格的评估结果,您不应该依赖这些结果,并且由于您的依赖性而使您的代码混乱它