每个cell有两种状态,alive和dead,分别用两种不同的颜色来表示
每个cell的状态变化受其周围8个cell影响
如果一个活的(alive)cell,其周围的活的cell数量少于2——即为0或1,则这个cell将死去(dead)
如果一个活的cell,其周围的活的cell数量超过3——即为4至8,则这个cell将死去
如果一个活的cell,其周围的活的cell数量为2或3,则它继续存活
如果一个死的cell,其周围的活的cell数量为3,则它成为活的cell,否则仍然为死的cell
"""Status manager of GOL(Game of Life).
Each world in game of life is a set of cells, and status of
every cell should be alive or dead. Status changes from gen
-eration to generation.
def
__init__
(
self
, row = 0, col = 0):
"""Init size and status of world."""
self
.row = row
self
.col = col
self
.now = {}
self
.
next
= {}
self
.init_status([])
def
init_status
(
self
, init_cells):
"""Set status of world.
if the begining status given is not empty, then use them
to initialize the world.
Args:
init_cells: begining status given. It's a tow-dimensional
array. Becase its size maybe smaller than the
world, we should be map each coordinate to the
center area of world.
#
code is hiden
def
update
(
self
):
"""Update status of world by status before.
For each cell in world, do these things:
1. look and find how many alive neighbors around,each cell
have eight neighbors
2. update status of cell according the number of its alive
neighbors. The following are the rules
+ if cell is alive, and number of neighbors is too small
(less than 2) or too too much(more than 3), this cell
will die, or it will be keep alive
+ if cell is dead, and number of neighbors is three, then
cell will be alive
#
code is hiden
def
neighbors
(
self
, row, col):
"""Compute number of alive neighbors around a cell."""
#
code is hiden
在这个类里,通过两个分别代表当前状态与将来状态的dict来进行状态的更新。在开始实现时犯了一个错误,就是在方法update()中,计算完self.next后,进行了一个错误的操作:
self.now = self.next
结果导致这两个类成员变量称为了同一个对象的引用,修改其中一者,另一者也发生改变,最后导致结果不正确。最后update()方法如下所示:
def update(self):
"""Update status of world by status before.
For each cell in world, do these things:
1. look and find how many alive neighbors around,each cell
have eight neighbors
2. update status of cell according the number of its alive
neighbors. The following are the rules
+ if cell is alive, and number of neighbors is too small
(less than 2) or too too much(more than 3), this cell
will die, or it will be keep alive
+ if cell is dead, and number of neighbors is three, then
cell will be alive
self.next = self.now.copy()
for crow in range(self.row):
for ccol in range(self.col):
around = self.neighbors(crow, ccol)
if (around < 2 or around > 3):
self.next[crow, ccol] = False
elif ((not self.now[crow, ccol]) and
around == 3):
self.next[crow, ccol] = True
self.now = self.next.copy()
# init resource
tk.Tk.__init__(self, *args, **kwargs)
self.setup_members() # initialize class members
self.setup_window() # root window
self.setup_toolbar() # tool bar
self.setup_canvas() # canvas to draw world
# init world
self.create_world()
# make world alive
self.after(5, lambda: self.life(5))
另外一些类方法就不列出来了,无非是绘图啊、事件响应啊什么的。代码我放到了Github上,如果需要,可以到这里 查看,或在本地执行:
git clone git@github.com:Linusp/pygol