The game of life(生命游戏)新算法
我写了一种常见的实现算法,和另一种新算法,即不是每次循环计算每个细胞的周围细胞数来产生下一时刻,而是每次每个产生状态变化的细胞主动通知周围的邻居,因此每个细胞增加一个用来记录邻居数的字段。由邻居数决定每个细胞的出生和死亡,然后影响周围邻居的邻居数。并且为了不影响后续细胞的判断,需要新旧邻居数两个状态,用旧邻居数决定自己生死,而自己的生死变化影响周围邻居的新邻居数。另外如果某个格子的新旧邻居数不变则状态不变,增加一个changed字段来表示。
下面分别是旧、新两种算法。
#include <stdio.h>
#include <stdlib.h> #define ROW 20
#define COL 60
#define FILEPATH "1.txt" int countNbor(char data[][COL],int i,int j);
void world(void); int main(void)
{
world();
return ;
} void world(void)
{
int i,j;
char data[ROW][COL];
char temp[ROW][COL];
int time=; FILE *fp=fopen(FILEPATH,"r"); for(i=;i<ROW;i++)
{
for(j=;j<COL;j++)
{
if(fgetc(fp)=='*') //表示细胞的字符
temp[i][j]=data[i][j]='*';
else temp[i][j]=data[i][j]=' ';
}
fgetc(fp);
}
fclose(fp); while()
{
time++; system("CLS");
for(i=;i<ROW;i++)
{
for(j=;j<COL;j++)
printf("%c",data[i][j]);
printf("\n");
}
printf("次数:%d\n",time); system("PAUSE>NUL"); for(i=;i<ROW;i++)
for(j=;j<COL;j++)
switch(countNbor(temp,i,j))
{
case :
data[i][j]='*';
break;
case :
break;
default:
data[i][j]=' ';
break;
} for(i=;i<ROW;i++)
for(j=;j<COL;j++)
temp[i][j]=data[i][j];
} } int countNbor(char data[][COL],int i,int j)
{
int m,n;
int count=; for(m=i-;m<=i+;m++)
for(n=j-;n<=j+;n++)
if( (m==i&&n==j) ||m<||n<||m==ROW||n==COL)
continue;
else if(data[m][n]=='*') count++; return count;
}
old.c
#include <stdio.h>
#include <stdlib.h> #define ROW 20
#define COL 60
#define FILEPATH "1.txt" typedef struct{
int live; //1、0表生死
int nbor_old; //旧邻居数,用于判断细胞生死
int nbor_new; //新邻居数,用于下一时刻
int changed; //邻居数是否变化
}Cell; typedef struct{
Cell cell[ROW+][COL+]; //+2留边
int lives_num; //细胞数目
int time_count; //第几轮
}World; void showWorld(World *world);
void sendNbor(Cell cell[][COL+],int i,int j,int live);
void processCell(World *world,int i,int j);
void iniWorld(World *world);
void runWorld(void); int main(void)
{
runWorld();
return ;
} void runWorld(void)
{
World world;
Cell (*cell)[COL+]=world.cell;
int i,j; //从文件初始化
iniWorld(&world); while()
{ world.time_count++;
showWorld(&world); //前提 cell[i][j].nbor_old==cell[i][j].nbor_new
//邻居数不变则状态不变,不用处理
for(i=;i<=ROW;i++)
for(j=;j<=COL;j++)
if(cell[i][j].changed)
processCell(&world,i,j); //判断自身,影响周围 for(i=;i<=ROW;i++)
for(j=;j<=COL;j++)
if(cell[i][j].nbor_old==cell[i][j].nbor_new)
cell[i][j].changed=;
else
{
cell[i][j].changed=;
cell[i][j].nbor_old=cell[i][j].nbor_new;
} }
} void iniWorld(World *world)
{
int i,j;
FILE *fp=fopen(FILEPATH,"r");
Cell (*cell)[COL+]=world->cell; world->time_count=;
world->lives_num=; for(i=;i<=ROW;i++)
{
for(j=;j<=COL;j++)
{
if(fgetc(fp)=='*') //表示细胞的字符
{
cell[i][j].live=;
world->lives_num++;
}
else
cell[i][j].live=; cell[i][j].nbor_new=cell[i][j].nbor_old=;
cell[i][j].changed=; //为了第一次循环每个细胞都能处理
}
fgetc(fp); //换行符
} fclose(fp); //填充nbor_old和nbor_new
for(i=;i<=ROW;i++)
for(j=;j<=COL;j++)
if(cell[i][j].live)
{
cell[i-][j-].nbor_old =++cell[i-][j-].nbor_new;
cell[i-][j].nbor_old =++cell[i-][j].nbor_new;
cell[i-][j+].nbor_old =++cell[i-][j+].nbor_new;
cell[i][j-].nbor_old =++cell[i][j-].nbor_new;
cell[i][j+].nbor_old =++cell[i][j+].nbor_new;
cell[i+][j-].nbor_old =++cell[i+][j-].nbor_new;
cell[i+][j].nbor_old =++cell[i+][j].nbor_new;
cell[i+][j+].nbor_old =++cell[i+][j+].nbor_new;
}
} //由old决定生死,并改变周围细胞的new
void processCell(World *world,int i,int j)
{
Cell (*cell)[COL+]=world->cell; switch(cell[i][j].nbor_old)
{
case :
if(!cell[i][j].live)
{
cell[i][j].live=;
sendNbor(cell,i,j,);
world->lives_num++;
}
break;
case : //不变
break;
default:
if(cell[i][j].live)
{
cell[i][j].live=;
sendNbor(cell,i,j,-);
world->lives_num--;
}
break;
}
} //细胞状态改变后,影响周围细胞的邻居值,live为-1或1
void sendNbor(Cell cell[][COL+],int i,int j,int live)
{
cell[i-][j-].nbor_new+=live;
cell[i-][j].nbor_new+=live;
cell[i-][j+].nbor_new+=live;
cell[i][j-].nbor_new+=live;
cell[i][j+].nbor_new+=live;
cell[i+][j-].nbor_new+=live;
cell[i+][j].nbor_new+=live;
cell[i+][j+].nbor_new+=live;
} void showWorld(World *world)
{
int i,j; system("CLS"); for(i=;i<=ROW;i++)
{
for(j=;j<=COL;j++)
{
if(world->cell[i][j].live)
printf("*");
else printf(" ");
}
printf("\n");
}
printf("细胞数:%d\n次数:%d\n",world->lives_num,world->time_count); system("PAUSE>NUL");
}
new.c
The game of life(生命游戏)新算法的更多相关文章
- LeetCode | 289. 生命游戏(原地算法/位运算)
记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...
- React项目(二):生命游戏
引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...
- 生命游戏 Java
本程序由四个类组成:其中Init_data,用于初始化各个活细胞的状态judge_state,用于判断下一代的细胞状态,并进行更新.set_color,用于给GUI界面中各个细胞涂色set_frame ...
- Conway生命游戏
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/9986679.html 作者:窗户 Q ...
- [Swift]LeetCode289. 生命游戏 | Game of Life
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- 【LeetCode】Game of Life(生命游戏)
这道题是LeetCode里的第289道题. 题目描述: 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格 ...
- Leetcode 289.生命游戏
生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状 ...
- 实用---生命游戏 Java
本程序由四个类组成: 其中Init_data,用于初始化各个活细胞的状态judge_state,用于判断下一代的细胞状态,并进行更新.set_color,用于给GUI界面中各个细胞涂色set_fram ...
- 生命游戏(python实现,pygame显示图形)
# 游戏规则:# 生命游戏(Game of Life),或者叫它的全称John Conway's Game of Life.是英国数学家约翰·康威在1970年代所发明的一种元胞自动机.# 1. 活细胞 ...
随机推荐
- linux教程:配置Tomcat开机启动
我们在linux下安装好tomcat之后:经常是需要配置到开机启动的: 这样的话就不需要我们每次重启linux服务器之后自己在登陆运行startup.sh文件启动tomcat了 本次的演示环境是在ce ...
- oracle - 创建数据库
在服务器端的oracle,用户有点差异,当 我通过 'sqlplus / as sysdba' 命令登陆后,并不能创建数据库,sysdba拥有最高的系统权限,登陆后是 sys,以as sysdba登录 ...
- OC - 27.CATransition
概述 简介 CATransition又称转场动画,是CAAnimation的子类,可以直接使用 转场动画主要用于为图层提供移入/移出屏幕的动画效果 转场动画常见的应用是UINavigationCont ...
- CoreMotion(加速计)
加速计的作用 用于检测设备的运动(比如摇晃) 加速计的经典应用场景 摇一摇 计步器 ********************************** Core Motion获取数据的两种方式 pu ...
- C# 多线程详解
1.使用多线程的几种方式 (1)不需要传递参数,也不需要返回参数 ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值. 复制代码 代码如下: cl ...
- 常见ORACLE错误,及解决方案(遇则即时更新)
1.当登陆时提示“ORA-03113:通信通道的文件结束”时: 解决方案: 需在X:\oraclexe\app\oracle\product\10 ...
- jquery获取form表单内容以及绑定数据到form表单
在日常开发的过程中,难免会用到form表单,我们需要获取表单的数据保存到数据库,或者拿到后台的一串json数据,要将数据绑定到form表单上,这里我写了一个基于jquery的,formHelp插件,使 ...
- Html 中select标签的边框与右侧倒三角的去除
首先是边框的去除:可以设置属性border:none;或border:0px; 不过这还是有一个bug,不同浏览器会在选中select标签时,加上一个边框: 之后是右侧倒三角的去除:设置属性 appe ...
- 使用appium做自动化时如何切换activity
在使用appium过程中遇到了执行一个用例时有多个不同的acitivity的情况,以下为app内部切换acitivity的方法: 如果仅需要切换一次activity,可以通过设置desired_cap ...
- elasticsearch 性能优化
#系统默认的最大打开文件数的限制 vi /etc/security/limits.conf * - nproc 50240 * - ...