添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1 背景说明

生命游戏,又叫康威生命游戏(Conway’s Game of Life),或康威生命棋,是英国数学家约翰·康威(John Conway)在1970年发明的细胞自动机。它最初在1970年10月在《科学美国人》杂志上的“数学游戏”专栏出现。我大一暑假在上暑期课程时无意中接触到这个概念,并被它看似简单的外表、实则复杂的“内心”所吸引,于是出于好奇就自己用C++模拟了一翻,直到最近整理本科成果时又一次翻到了这个小巧有趣的代码。代码很短,只有一二百行,其中核心的判断和计算的部分只有十来行;其算法更是简单,几句话就可以描述清楚。下面我将做简要的介绍。

2 算法原理

2.1 概述

生命游戏是一个零玩家游戏。它发生在一个二维矩形世界,这个世界的基本组成单位是一个一个等大的小方格。每个方格居住着一个活着的或死了的细胞。一个细胞在下一个时刻生死取决于相邻八个方格中活着的细胞的数量。一方面,如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;另一方面,如果周围活细胞过少,这个细胞会因太孤单而死去。而只有其周围的细胞数量适合时,这个方格中的细胞才能继续存活。若方格中原来的细胞已经死亡,在其周围细胞数量合适时,也会使得该死细胞“死而复生”,这可以认为是在模拟细胞的繁殖。玩家可以设定周围活细胞的数目怎样时才事宜细胞生存和繁殖。但是需要注意的是,如果这个数目设定过高,世界中的大部分细胞会因为找不到太多的活的邻居而死去,直到整个世界都没有生命;如果这个数目设定过低,世界中又会被生命充满而没有什么变化。

实际游戏中,这个数目一般选取2或者3;这样整个生命世界才不至于太过荒凉或拥挤,而是出于一种动态平衡之中。如此一来,游戏的规则就是:当一个方格周围有2或3个活细胞时,方格中的活细胞在下一个时刻继续存活;即使这个时刻方格中没有活细胞,在下一个时刻也会“诞生”活细胞。否则,这个方格中的细胞会死亡,或不诞生新的活细胞。

2.2 规则

在选取了合适的数据后,对具体规则作如下描述。

生命游戏中,对于任意细胞:
每个细胞有两种状态:存活或死亡。每个细胞与以自身为中心的周围八格细胞产生互动。
1.当前细胞为存活状态时,当周围的活细胞低于2个时, 该细胞因孤独而死亡;
2.当前细胞为存活状态时,当周围有2个或3个活细胞时, 该细胞保持原样;
3.当前细胞为存活状态时,当周围有3个以上活细胞时,该细胞因资源匮乏而死亡;
4.当前细胞为死亡状态时,当周围有3个活细胞时,该细胞变成存活状态(模拟繁殖)。

3 程序实现

我用C++模拟了上述过程。此算法的核心在于计算下一代细胞的存亡图景,代码如下所示:

void NextG(int p[][MAXLIS],int q[][MAXLIS])               
	int i,j,x,y;
	int judge;
	for(i = 0;i < MAXROW;i++)
		for(j = 0;j < MAXLIS;j++)
			if(p[i][j] == ALIVE)
				judge = -1;                         //每一轮结束judge都要复位
			else if(p[i][j] == DEAD)
				judge = 0;
			for(x = MAX(i-1,0);x<=MIN(i+1,MAXROW-1);x++)     //开始这里的MAXROW和MAXLIS后面忘记-1,逻辑出错找了好久
				for(y = MAX(j-1,0);y<=MIN(j+1,MAXLIS-1);y++)
					if(p[x][y] == ALIVE)
						judge +=1;
			switch(judge)
			case 2:q[i][j] = p[i][j];break;			// 周围有2个活细胞,保持原样
			case 3:q[i][j] = ALIVE;break;			// 周围有3个活细胞,生则继续,死则复活(模拟繁殖)
			default:q[i][j] = DEAD;break;			// 周围有1或4-8个活细胞,死(模拟拥挤而死或孤独而死)

   代码本身可以说是相当简单了,学过数组的人都能写出来。剩下的就是一些装饰门面的活儿,比如说我当时写的测试代码——即main()函数——是长这个样子的:

int main()
	int CHOICE = 1,n = 0;
	int choice;
	int map[MAXROW][MAXLIS] = {DEAD},newmap[MAXROW][MAXLIS] = {DEAD};		//定义2个同维数组并初始化为全0数组	
	cout<<"_________________________________________"<<endl;
	cout<<"|                                        |"<<endl;
	cout<<"|    欢迎来到“生命游戏”!                  |"<<endl;
	cout<<"|                                        |"<<endl;
	cout<<"|    请选择初始化模式:                    |"<<endl;
	cout<<"|                                        |"<<endl;
	cout<<"|       1.自动模式A     2.自动模式B        |"<<endl;
	cout<<"|                                        |"<<endl;
	cout<<"|       3.随机模式      4.手动模式         |"<<endl;
	cout<<"|________________________________________|"<<endl;
	cin>>choice;
	switch(choice)
	case 1:Init1(map);break;               //二维数组作为函数参数被调用时,参数是二维数组的起始位指针,也就是数组名
	case 2:Init2(map);break;
	case 3:Init3(map);break;
	case 4:Init4(map);break;
	default:
			cout<<"默认为随机初始化模式."<<endl;
			Init3(map);
			break;
	cout<<endl<<"父代细胞生存图:"<<endl;
	ShowMap(map);
	while(CHOICE)
		NextG(map,newmap);
		CopyClc(map,newmap);
		cout<<endl<<"子"<<n++<<"代细胞生存图:"<<endl;
		ShowMap(map);
		cout<<"\n继续请按除0以外的任意数字键."<<endl;
		cin>>CHOICE;
	cout<<"您已退出游戏."<<endl;
	return 0;

   这里我给出了4种初始化的条件供用户选择,同时为了让用户看清中间的每一个步骤,我让用户自己步进操作,也省了设置步进时长的麻烦,当然这些都是小细节。另外,很多人直接把这个例程写在了网页上,大家也可以去感受一下,推荐的网址有链接1链接2

4 结果分析

   代码跑通之后就可以随意玩耍了!运行的界面如图1所示:

 
   情形四恰好包含了情形一到情形三的内容,当然也是稳定的。

   “生命游戏”虽然是一个零玩家游戏,但却经久不衰。它一直吸引着大量的爱好者的视线,其中包含的乐趣当然不止我所描述的这些。只要上网一查就能找到许多有趣的讨论,比如知乎对生命游戏稳定图形的探讨、果壳网对于计算和宇宙的关系的专访报告以及哔哩哔哩YouTube上的一些有趣视频等,如果你有兴趣,此话题大有继续探讨的空间和价值。

   转载时务必注明来源及作者。尊重知识产权从我做起。

   代码已上传至网络,欢迎下载,密码是9hrg

它的规则是这样的: 对其中一个网格,如果它的邻居少于两个,则它会死于孤独;如果多于三个,它亦会因拥挤而死。只有当它的邻居数等于二或三时它才会生存到下一代;如果某格原先没有细胞,但它有三个邻居时,会繁衍一个新的细胞。 以上是百度到的介绍。这个程序是我自己写的,只用到了,用的是二维数组,在控制台显示,所以范围比较有限。 在交互式监视模式下启动测试运行器。 有关更多信息,请参见关于的部分。 yarn build 构建生产到应用程序build文件夹。 它在生产模式下正确捆绑了React,并优化了构建以获得最佳性能。 生成被最小化,并且文件名包括哈希值。 您的应用已准备好进行部署! 有关更多信息,请参见关于的部分。 yarn eject 注意:这是单向操作。 eject ,您将无法返回! 如果您对构建工具和配置选择不满意,则可以随时eject 。 此命令将从您的项目中删除单个生成依赖项。 相反,它将所有配置文件和传递依赖项(webpack,Babel,ESLint等)直接
最初写这段代码是为了2019华为软件精英挑战赛准备,熟悉元胞自动机用。最终发现并没有留给我写判题器的时间。但这段代码还是保留下来了,存储gif的部分借鉴了别的博客,不过已经找不到原文了。这段代码写的不是很好,在我的电脑上运行很慢(还是自己优化水平太差),也算自己独立实现的,放在博客上自省。 生命游戏实现 生命游戏的规则可参考:生命游戏简介及算法分析(整理) 代码中可对burn、live、init、...
According to the Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.” Given a board with m by n ...
生命游戏 生命游戏game of life)为1970年由英国数学家J. H. Conway所提出,某一细胞的邻居包括上、下、左、右、左上、左下、右上与右下相邻之细胞。 生命游戏中,对于任意细胞,规则如下: 每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。 当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖) 当前细胞为存活状...
根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律: 如果活细胞周围八个位置的活细胞数少于两个,则该...
don(difference of normal)算法是一种用于图像处理的算法,主要用于增强图像的细节和纹理。这个算法通过计算图像中像素点与其周围像素的差异,并将其应用于原始图像,以增强图像的细节特征。 don算法的步骤如下: 1. 首先,对原始图像进行归一化处理,将图像的像素值缩放到0到1之间,以方便后续处理。 2. 然后,对图像进行高斯滤波,以去除图像中的噪声和平滑图像。高斯滤波可以采用不同的半径和标准差,以适应不同的图像。 3. 接下来,计算图像中每个像素点与其周围像素的差异。差异可以使用梯度算子(如Sobel算子)来计算,或者使用拉普拉斯算子来计算。差异值表示了每个像素点的细节特征。 4. 最后,将差异值应用于原始图像。可以通过将差异值与原始图像的像素值相乘,或者通过将差异值加到原始图像上来实现。这样可以增强图像的细节和纹理,使图像变得更加清晰和饱满。 don算法在图像处理领域有着广泛的应用。它可以用于增强图像的边缘和纹理特征,改善图像的清晰度和细节表达。与其他算法相比,don算法具有计算简单、效果明显、适用范围广等优点,因此在实际应用中得到了广泛的应用。