生命游戏

生命游戏的宇宙是一个无限的,其中细胞的二维正交网格,每个细胞处于两种可能的状态之一,即*活着*或*死亡*(分别是*人口稠密*和*无人居住*)。每个细胞与它的八个邻居相互作用,这八个邻居是水平,垂直或对角相邻的细胞。在每一步中,都会发生以下转换:

  1. 任何有两个以上活着的邻居的活细胞都会死亡,好像是在人口下一样。
  2. 任何有两三个活着的邻居的活细胞都会生活在下一代。
  3. 任何有三个以上活着的邻居的活细胞都会死亡,就好像人口过剩一样。
  4. 任何具有三个活的邻居的死细胞都会变成一个活细胞,就像是通过繁殖一样。

其简单动画效果如:

其主要实现逻辑代码出自Effective Python一书中。不过原代码中的生命游戏是静止的,把每一代分别打印出来,没有动画效果,我增加部分代码,实现在终端的动画效果。
动画实现原理是:

\x1b[nA]   光标上移
\x1b[nB]   光标下移
\x1b[nC]   光标右移
\x1b[nD]   光标左移
(n为字符数)

控制光标位置是通过ANSI转义符实现的。从这篇文章获得相关知识的:https://www.zhihu.com/question/21100416/answer/208143599

  第一代细胞(预设生存环境在 X * Y 的二维平面方格上)随机生成,将其打印在控制台上,然后此时控制台光标会从初始位置(方格左上角(1,1)上)到方格右下角(X,Y)的位置。下一代细胞打印前通过移动控制台的光标到初始位置(1,1)上,此后的打印这代细胞就会覆盖前一代细胞。造成视觉上的动画效果。

全部代码如下:

 import os
import sys
import time
import random
from collections import namedtuple ALIVE = '*'
EMPTY = ' ' Query = namedtuple('Query', ('y', 'x')) def count_neighbors(y, x):
n_ = yield Query(y + 1, x + 0) # North
ne = yield Query(y + 1, x + 1) # Northeast
e_ = yield Query(y + 0, x + 1) # East
se = yield Query(y - 1, x + 1) # Southeast
s_ = yield Query(y - 1, x + 0) # South
sw = yield Query(y - 1, x - 1) # Southwest
w_ = yield Query(y + 0, x - 1) # West
nw = yield Query(y + 1, x - 1) # Northwest
neighbor_states = [n_, ne, e_, se, s_, sw, w_, nw]
count = 0
for state in neighbor_states:
if state == ALIVE:
count += 1
return count Transition = namedtuple('Transition', ('y', 'x', 'state')) def step_cell(y, x):
state = yield Query(y, x)
neighbors = yield from count_neighbors(y, x)
next_state = game_logic(state, neighbors)
yield Transition(y, x, next_state) def game_logic(state, neighbors):
if state == ALIVE:
if neighbors < 2:
return EMPTY # Die: Too few
elif neighbors > 3:
return EMPTY # Die: Too many
else:
if neighbors == 3:
return ALIVE # Regenerate
return state TICK = object() def simulate(height, width):
while True:
for y in range(height):
for x in range(width):
yield from step_cell(y, x)
yield TICK class Grid(object):
def __init__(self, height, width):
self.height = height
self.width = width
self.rows = []
for _ in range(self.height):
self.rows.append([EMPTY] * self.width) def query(self, y, x):
return self.rows[y % self.height][x % self.width] def assign(self, y, x, state):
self.rows[y % self.height][x % self.width] = state def random_alive(self, live_count):
xy = [(i,j) for i in range(self.width) for j in range(self.height)]
for i,j in random.sample(xy, live_count):
self.assign(i, j, ALIVE) def live_a_generation(self,grid, sim):
# self.change_state(EMPTY)
progeny = Grid(grid.height, grid.width)
item = next(sim)
while item is not TICK:
if isinstance(item, Query):
state = grid.query(item.y, item.x)
item = sim.send(state)
else: # Must be a Transition
progeny.assign(item.y, item.x, item.state)
item = next(sim)
return progeny def __str__(self):
output = ''
for row in self.rows:
for cell in row:
output += cell
output += '\n'
return output.strip() def main(x,y,k):
os.system('cls') # linux 为 clear
grid = Grid(x, y)
grid.random_alive(k)
clear = '\x1b[{}A\x1b[{}D'.format(x,y)
print(grid, end='')
sim = simulate(grid.height, grid.width)
while 1:
time.sleep(.1)
grid = grid.live_a_generation(grid, sim)
print(clear)
print(grid, end='')
time.sleep(.1)
print(clear) if __name__ == '__main__':
main(30,40,205)

最新文章

  1. Mac下的类似apt-get的包管理工具Homebrew(笔记)
  2. sprintf()函数的用法
  3. 论SCRM系统对传统行业的冲击
  4. HiveQL(HiveSQL)跟普通SQL最大区别一直使用PIG,而今也需要兼顾HIVE
  5. 第二十六课:jQuery对事件对象的修复
  6. Android Loader详解
  7. 笔记13:File 类的一些操作
  8. 20145236 《Java程序设计》 第十周学习总结
  9. smarty缓存技术
  10. 【USACO 1.3.3】回文串
  11. Java学习----你可以告诉对象该怎么做(方法中传参)
  12. dig挖出DNS的秘密
  13. SOUI视频教程
  14. 单双通道对RTX有何影响?结果出乎意料
  15. selenium chromedriver geckodriver iedriverserver下载
  16. var let const
  17. gear gym 思维题
  18. 美国主机BlueHost vs HostEase
  19. js 获取时区
  20. Qt编写软件运行时间记录(开源)

热门文章

  1. Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 报错
  2. TCPlayer web切换播放问题
  3. PHP通过身份证号码获取性别、出生日期、年龄等信息
  4. js生成二维码并保存成图片下载
  5. python学习Day8 三种字符类型、文件操作
  6. dotnet不是内部或外部的命令,也不是可运行的程序或批处理文件
  7. flutter Dialog里ListView的问题
  8. WEB-INF目录下的jsp怎么引用外部文件:js,css等
  9. UEFI EVENT 全解
  10. OJ题解记录计划