康威生命游戏其实很简单,如果不用花里胡哨的那么多函数调用,或者定义类的要求,最简单运用numpy的应该就是这种了。
一. 整体思路
首先,要清楚知道程序分为几个部分,我们需要熟悉规则,想要达到的效果就是细胞在不断死亡和活过来,也就是运用numpy,创建一个方阵,通过它的规则使其不断地迭代,直到最终稳定下来。
其次,我们还需要一个窗口去展示这个迭代的过程,这里运用的是pygame这个包,这个包可以设计窗口的大小,所编写程序的名字等等。
最后整合到一起去,完整的展示出整体过程。
游戏规则
当周围仅有1个或没有存活细胞时, 原来的存活细胞进入死亡状态。
当周围有2个或3个存活细胞时, 网格保持原样。
当周围有4个及以上存活细胞时,原来的存活细胞亦进入死亡状态。
当周围有3个存活细胞时,空白网格变成存活细胞。
二. 具体编写
1.设计窗口大小以及把其分为网格
首先确定窗口的大小是600×600,X,Y是网格的数量,这取决于你自己创建的矩阵的大小,这里是50×50的矩阵,矩阵里的元素就是占这里的一个网格的大小,后面就说是一个cell的大小。
其次确定大小后,细胞如何展示,这里通过定义颜色的RGB的值,来给细胞上色。如下所示,我们定义了活着的状态和死亡的状态,以便后面用到。
ALIVE = (124, 252, 0) # 括号里就是RGB的值,可以自己查找想要的颜色的值 绿色
DEAD = (0, 0, 0) # 黑色
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
X = 50 # X方向的网格数量
Y = 50 # Y方向的网格数量
CELL_WIDTH = SCREEN_WIDTH / X
CELL_HEIGHT = SCREEN_HEIGHT / Y
2. 导入模块
import pygame,sys, random
import numpy as np
3. 初始化矩阵
创建一个矩阵,遍历每一个元素,设置随机数,默认在0~1的随机数,ran即为概率也就是细胞的密度。
def initialization():
matrix = np.full((50, 50), 0)
for i in range(50):
for j in range(50):
ran = random.random()
if ran > 0.6:
matrix[i][j] = 1
else:
pass
return matrix
4.迭代矩阵
创建一个新的矩阵,在原有矩阵的基础上,增加一个边界,也就是行和列都加两行。并将其作为一个存放数据的内存,将原矩阵元素复制过来,保证边框没有元素。由于规则是细胞的8个邻居,但是边界的细胞并没有那么多,所以新建的矩阵加了行和列,尽管令其为0,但是也使规则适用于所有细胞,使程序更加完整。
def evolution(matrix):
new_matrix = np.full((52, 52), 0)
num = 0
for i in range(50):
for j in range(50):
new_matrix[i+1][j+1] = matrix[i][j]
for i in range(1,51):
for j in range(1,51):
num = new_matrix[i-1][j-1]+new_matrix[i-1][j]+new_matrix[i-1][j+1]+new_matrix[i][j-1]+new_matrix[i][j+1]+new_matrix[i+1][j-1]+\
new_matrix[i+1][j]+new_matrix[i+1][j+1]
if new_matrix[i][j] == 0: # 若原细胞为死亡状态
if num == 3:
matrix[i-1][j-1] = 1
else: # 若原细胞为存活状态
if num == 2 or num == 3:
matrix[i-1][j-1] = 1
else:
matrix[i-1][j-1] = 0
return matrix
另外,也可以直接令其边界的细胞为0,也就是展示的时候,边界细胞始终是死的,也就是这样
def nextmultiply(arr): #下一代繁衍
newarr = [([0] * width) for n in range(high)]
for i in range(high):
for j in range(width):
num=0
if (i==0 or i==high-1) or (j==0 or j==width-1):
newarr[i][j]=0
else:
num=arr[i-1][j-1]+arr[i-1][j]+arr[i-1][j+1]+arr[i][j-1]+arr[i][j+1]+arr[i+1][j-1]+arr[i+1][j]+arr[i+1][j+1] # 可以的
if arr[i][j]==0: #若原细胞为死亡状态
if num==3:
newarr[i][j]=1
else: #若原细胞为存活状态
if num==2 or num==3:
newarr[i][j]=1
else:
newarr[i][j]=0
return newarr
5. 除此之外,还需要使用pygame,一般固定格式
if __name__ == "__main__": # 当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行
# pygame初始化的相关内容
pygame.init() # 使用pygame之前必须初始化
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 创建游戏的主窗口对象
screen.fill(DEAD) # 使屏幕全变成黑色,初始化屏幕
pygame.display.set_caption("康威生命游戏") # 设置窗口的标题,即游戏名称
framerate = pygame.time.Clock() # 创建一个Clock对象,用于操作时间
for event in pygame.event.get(): # 判断用户是否点了"X"关闭按钮,并执行if代码段
if event.type == pygame.QUIT:
pygame.quit() # 卸载所有模块
sys.exit() # 终止程序,确保退出程序
pygame.display.update() # 对显示窗口进行更新,默认窗口全部重绘 pygame.display.update():刷新主窗口内容
framerate.tick(10) # 设置每秒10帧
6. 最后整体代码如下:
ALIVE = (124, 252, 0) # 绿色
DEAD = (0, 0, 0) # 黑色
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
X = 50 # X方向的网格数量
Y = 50 # Y方向的网格数量
CELL_WIDTH = SCREEN_WIDTH / X
CELL_HEIGHT = SCREEN_HEIGHT / Y
import pygame,sys, random
import numpy as np
def initialization():
matrix = np.full((50, 50), 0)
for i in range(50):
for j in range(50):
ran = random.random()
if ran > 0.6:
matrix[i][j] = 1
else:
pass
return matrix
def evolution(matrix):
new_matrix = np.full((52, 52), 0)
num = 0
for i in range(50):
for j in range(50):
new_matrix[i+1][j+1] = matrix[i][j]
for i in range(1,51):
for j in range(1,51):
num = new_matrix[i-1][j-1]+new_matrix[i-1][j]+new_matrix[i-1][j+1]+new_matrix[i][j-1]+new_matrix[i][j+1]+new_matrix[i+1][j-1]+\
new_matrix[i+1][j]+new_matrix[i+1][j+1]
if new_matrix[i][j] == 0: # 若原细胞为死亡状态
if num == 3:
matrix[i-1][j-1] = 1
else: # 若原细胞为存活状态
if num == 2 or num == 3:
matrix[i-1][j-1] = 1
else:
matrix[i-1][j-1] = 0
return matrix
if __name__ == "__main__": # 当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行
# pygame初始化的相关内容
pygame.init() # 使用pygame之前必须初始化
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 创建游戏的主窗口对象
screen.fill(DEAD) # 使屏幕全变成黑色,初始化屏幕
pygame.display.set_caption("康威生命游戏") # 设置窗口的标题,即游戏名称
framerate = pygame.time.Clock() # 创建一个Clock对象,用于操作时间
# 主函数
matrix = initialization() # 初始化
while True: # 循环获取事件,监听事件状态
screen.fill(DEAD) # 使屏幕全变成黑色,初始化屏幕
for i in range(Y): # 遍历矩阵,并上色
for j in range(X):
if matrix[i][j] == 1:
pygame.draw.rect(screen, ALIVE, (i * CELL_WIDTH, j * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT))
else:
pygame.draw.rect(screen, DEAD, (i * CELL_WIDTH, j * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT))
for event in pygame.event.get(): # 判断用户是否点了"X"关闭按钮,并执行if代码段
if event.type == pygame.QUIT:
pygame.quit() # 卸载所有模块
sys.exit() # 终止程序,确保退出程序
matrix = evolution(matrix)
pygame.display.update() # 对显示窗口进行更新,默认窗口全部重绘 pygame.display.update():刷新主窗口内容
framerate.tick(10) # 设置每秒10帧