defnext_generation(world): "The set of live cells in the next generation." possible_cells = counts = neighbor_counts(world) return {cell for cell in possible_cells if(counts[cell] == 3) or (counts[cell] == 2and cell in world)}
defneighbor_counts(worlds): "A {cell: int} counter of the number of live neighbors for each cell that has neighbors." return Counter(nb for cell in world for nb in neighbors(cell))
defneighbors(cell): "All 8 adjacent neighbors of cell." x, y = cell return [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y), (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)]
run函数可以生成N代
1 2 3 4
defrun(world, n): for g in range(n): world = next_generation(world) return world
展示(display)
现在我们看下如何展示世界。
1 2 3 4 5 6 7 8 9 10 11
import time from IPython.display import clear_output, display_html
LIVE = '@' EMPTY = '.' PAD = ' '
defpicture(world, Xs, Ys): "return a picture: agrid of characters representing the cells in this window." defrow(y):return PAD.join(LIVE if (x, y) in world else EMPTY for x in Xs) return'\n'.join(row(y) for y in Ys)
1
print(picture(world, range(5), range(5)))
1 2 3 4 5
. . . . . . . . @ . . @ . . . . @ @ . . . . . . .
下面这个函数在每一步展示出图片
1 2 3 4 5 6 7 8 9 10 11
defdisplay_run(world, n=10, Xs=range(10), Ys=range(10), pause=0.2): "Step and display the world for the given number of generations." for g in range(n + 1): html = ('Generation {}, Population {}\n{}' .format(g, len(world), pre(picture(world, Xs, Ys)))) clear_output() display_html(html, raw=True) time.sleep(pause) world = next_generation(world) defpre(text):return'<pre>' + text +'</pre>'
defshape(picture, offset=(3, 3)): "Convert a graphical picture into a world(set of cells)" cells = {(x, y) for (y, row) in enumerate(picture.splitlines()) for (x, c) in enumerate(row.replace(PAD, '')) if c == LIVE} return move(cells, offset)
defmove(cells, offset): "Move/Translate/slide a set of cells by a (dx, dy) displacement/offset." (dx, dy) = offset return {(x + dx, y + dy) for (x, y) in cells} blinker = shape("@@@") block = shape("@@\n@@") beacon = block | move(block, (2, 2)) toad = shape(".@@@\n@@@.") glider = shape(".@.\n..@\n@@@") rpentomino = shape(".@@\n@@.\n.@.", (36, 20)) line = shape(".@@@@@@@@.@@@@@...@@@......@@@@@@@.@@@@@", (10, 10)) growth = shape("@@@.@\n@\n...@@\n.@@.@\n@.@.@", (10, 10))
不用IPython
如果要在Ipython/Jupyter notebook之外的终端中运行此代码,可以删除:
1 2
from IPython.display import clear_output, display_html
加上
1 2 3 4 5
defclear_output(): print("\033[;H\033[2J") # ANSI terminal home and clear