一.定义
1.二维元胞自动机
所谓二维元胞自动机,就是当前元胞的状态不但可以由左右元胞决定,还能被上下元胞,甚至是其他二维平面内的元胞状态决定。
2.生命游戏(game of life)
生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。它最初于1970年10月在《科学美国人》杂志中马丁·葛登能(Martin Gardner,1914年11月21日-2010年5月22日。又译:马丁·加德纳)的“数学游戏”专栏出现。(百度百科)
多的不想bb了,心痛,有空再补,自行百度。
二.思路
1.游戏规则设置
这里设置的规则是
当前元胞是活的,周围8个元胞中有两个或三个元胞活着,那么继续活着(1)
当前元胞是死的话,如果周围8个元胞中有3个元胞活着,那么这个元胞复活从0变成1
2.初始化元胞数组可以把整个数组行列扩大2,可以保证每个元胞都可以计算周围8个活着的元胞的数目之和
是为了让边边上的元胞可以好好的玩耍
假设有9个元胞,为了让每个元胞都可以快乐玩耍(有8个邻居),我们把这个数组横竖扩大两个维度
这样的话像1号元胞就有3个真的伙伴,5个假的伙伴,但无所谓,1已经很满足了,心里不会比5的感觉差太多,有底气的多了
如上图
3.这里有个好玩的函数sumfun(),可以快速拿到每个元胞周围8个活着的元胞的数目之和
假设上方的3*3元胞矩阵的辅助扩大的5*5矩阵为A
我们可以通过一个好玩的方式拿到 每个元胞对应的周围8个活着元胞的数目矩阵B
这个矩阵首先是3*3的,可以通过辅助矩阵中8个3*3的矩阵相加拿到
这是前3个矩阵
这是中间两个矩阵
这是下面3个矩阵
这8个矩阵相加为啥最后就是B呢?
你可以考虑着8个矩阵左上角的元素相加是个啥,再思考其他位置的,立即推,你可真秀。
三.代码+解析
1.第一部分,参数设置,初始化
function my_game_of_life()
n=500; //一共500*500个元胞
step=1000; //迭代步数自己设置,这里是1000步
big_matrix=round(rand(n+2)); //这就是上面介绍的辅助扩大矩阵(round是估计函数,rand是随机生成数的函数)
real_matrix=big_matrix(2:end-1,2:end-1); //这是实际的元胞矩阵
grayscale_image=imshow(real_matrix,[]); //把real_matrix放到grayscale_image中用来显示成灰度图像
figure(gcf); %打开窗口gcf
set(gcf,'doublebuffer','on'); %打开双缓冲技术
2.进入版本迭代
while(step>0)
if findobj==0 //网上找的代码关掉figure会报错,因为没有跳出while循环
break; //这里通过findobj找到当前的对象,应该是figure对象,如果你关掉figure,这里就是0
end
A=sumfun(big_matrix); %本次迭代图像对应的邻居数
X=zeros(n); %本次迭代矩阵初始化
X(real_matrix==1&(A==2|A==3))=1; //1-1 继续存活规则 是周围有两个或者3个令居
X(real_matrix==0& A==3)=1; //0-1 复活规则 周围有3个令居
big_matrix(2:end-1,2:end-1)=X; %把这次迭代的图塞进大图里
real_matrix=X; %这次迭代的图
set(grayscale_image,'CData',1-X); //这里是每次刷新图的关键,算是重绘
pause(0.5); //停留0.5s
end
end
function sum=sumfun(B) //求邻居数函数sumfun()
sum=B(1:end-2,1:end-2)+...
B(1:end-2,2:end-1)+...
B(1:end-2,3:end)+...
B(2:end-1,1:end-2)+...
B(2:end-1,3:end)+...
B(3:end,1:end-2)+...
B(3:end,2:end-1)+...
B(3:end,3:end);
end
四.源码
function my_game_of_life()
n=500;
step=1000;
big_matrix=round(rand(n+2));
real_matrix=big_matrix(2:end-1,2:end-1);
grayscale_image=imshow(real_matrix,[]); %把real_matrix放到grayscale_image中用来显示成灰度图像
figure(gcf); %打开窗口gcf
set(gcf,'doublebuffer','on'); %打开双缓冲技术
while(step>0)
if findobj==0
break;
end
A=sumfun(big_matrix); %本次迭代图像对应的邻居数
X=zeros(n); %本次迭代矩阵初始化
X(real_matrix==1&(A==2|A==3))=1;
X(real_matrix==0& A==3)=1;
big_matrix(2:end-1,2:end-1)=X; %把这次迭代的图塞进大图里
real_matrix=X; %这次迭代的图
set(grayscale_image,'CData',1-X);
pause(0.5);
end
end
function sum=sumfun(B)
sum=B(1:end-2,1:end-2)+...
B(1:end-2,2:end-1)+...
B(1:end-2,3:end)+...
B(2:end-1,1:end-2)+...
B(2:end-1,3:end)+...
B(3:end,1:end-2)+...
B(3:end,2:end-1)+...
B(3:end,3:end);
end
五.小结
这里这个findobj有点东西,可以理解成监听figure关闭的一个东西
最后的图大致如下