其中一种较为丰富的设定有如下四条:
根据这些资料,笔者在R中运行了相应的代码,首先运行1000次的演变过程,记录每个时间点上细胞的总数,根据这些变化的数字可以得到如下的图形。可以看到一开始细胞过多而出现大量死亡,在接近灭绝的时候又由于资源的空闲而大量繁殖,但繁殖存在一个上限,之后存活数目呈上下振荡趋势。
另一种玩法是不限定演变的次数,而是反复绘图,以上帝的视角观察这个二维世界中“人们”的变化。看它们生生死死、潮起潮落。在游戏的进行中,杂乱无序的细胞会逐渐演化出各种精致、有形的结构;有时,一些已经成形的结构会因为一些无序细胞的“入侵”而被破坏。但是形状和秩序经常能从杂乱中产生出来。
注:本文参考了wiki,以及《Introduction to Scientific Programming and Simulation Using R》第五章的习题。
R代码:
rm(list=ls())
#建立一个计算邻近存活细胞数目的函数,并使边缘的细胞仍有八个邻居
neighbours <- function(A,i,j,n) {
left <- ifelse(j == 1,n,j-1)
right <- ifelse(j == n, 1, j+1)
up <- ifelse(i == 1, n, i-1)
down <- ifelse(i == n, 1, i+1)
nbrs <- sum(A[up,left] == 1,A[up,right] == 1,A[up,j] == 1,A[i,left] == 1, A[i,right] == 1,A[down,left] == 1,A[down,right] == 1,A[down,j] == 1)
return(nbrs)
}
n <- 50 #方阵的行数
A <- matrix(round(runif(n^2)),n,n) #初始化二维世界方阵
finished <- FALSE
while (!finished) { #重复进行演化,你需要用ESC退出
plot(c(1,n),c(1,n),type='n',xlab='',ylab='') #绘图
for(i in 1:n) {
for (j in 1:n) {
if (A[i,j]==1) {
points(i,j,pch=16,col='red')
}
}
}
B <- A #将上期的信息存入本期矩阵B,并按照条件修改B
for (i in 1:n) {
for (j in 1:n) {
nbrs <- neighbours(A,i,j,n)
if (A[i,j]==1) {
if ((nbrs ==2) | (nbrs==3)){
B[i,j] <- 1
} else {
B[i,j] <- 0
}
} else {
if (nbrs ==3) {
B[i,j] <- 1
} else {
B[i,j] <- 0
}
}
}
}
A <- B #将变化后的B矩阵存回到A中
}
玩过这个没有:
回复删除demo('game_of_life', package='animation', ask=FALSE)
原来animation包里头已经有这个了
删除