我写了一种常见的实现算法,和另一种新算法,即不是每次循环计算每个细胞的周围细胞数来产生下一时刻,而是每次每个产生状态变化的细胞主动通知周围的邻居,因此每个细胞增加一个用来记录邻居数的字段。由邻居数决定每个细胞的出生和死亡,然后影响周围邻居的邻居数。并且为了不影响后续细胞的判断,需要新旧邻居数两个状态,用旧邻居数决定自己生死,而自己的生死变化影响周围邻居的新邻居数。另外如果某个格子的新旧邻居数不变则状态不变,增加一个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(生命游戏)新算法的更多相关文章

  1. LeetCode | 289. 生命游戏(原地算法/位运算)

    记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...

  2. React项目(二):生命游戏

    引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...

  3. 生命游戏 Java

    本程序由四个类组成:其中Init_data,用于初始化各个活细胞的状态judge_state,用于判断下一代的细胞状态,并进行更新.set_color,用于给GUI界面中各个细胞涂色set_frame ...

  4. Conway生命游戏

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/9986679.html 作者:窗户 Q ...

  5. [Swift]LeetCode289. 生命游戏 | Game of Life

    According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...

  6. 【LeetCode】Game of Life(生命游戏)

    这道题是LeetCode里的第289道题. 题目描述: 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格 ...

  7. Leetcode 289.生命游戏

    生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状 ...

  8. 实用---生命游戏 Java

    本程序由四个类组成: 其中Init_data,用于初始化各个活细胞的状态judge_state,用于判断下一代的细胞状态,并进行更新.set_color,用于给GUI界面中各个细胞涂色set_fram ...

  9. 生命游戏(python实现,pygame显示图形)

    # 游戏规则:# 生命游戏(Game of Life),或者叫它的全称John Conway's Game of Life.是英国数学家约翰·康威在1970年代所发明的一种元胞自动机.# 1. 活细胞 ...

随机推荐

  1. Android开发手记(26) Java多线程的实现

    随着多核CPU的发展,多线程编程显得越来越重要,本文将对Java中的多线程编程进行一些简单的探讨. 1.继承Thread类 Java中,线程运行的基本单位是Thread,所以,我们可以通过继承Thre ...

  2. 多线程 - 线程同步锁(lock、Monitor)

    1. 前言 多线程编程的时候,我们不光希望两个线程间能够实现逻辑上的先后顺序运行,还希望两个不相关的线程在访问同一个资源的时候,同时只能有一个线程对资源进行操作,否则就会出现无法预知的结果. 比如,有 ...

  3. 掌握JS

    1.原生的js,好比全真教的武功,一步步从基础开始(先练气再御剑),很长一段时间内和jquery有很大差距,掌握以后发现jquery只不过是另外一种武功,看一遍既会.且当学原生到一定程度之后,可以自创 ...

  4. java中的继承要点

    java的一大特性既是:继承. 1.因为有了一个子类继承了一个父类,才有了后面的多态. 2.类的继承,不要为了节省代码,为了继承而继承,把那个没有任何相关的类链接在一起,继承必须用在 is a,就是例 ...

  5. Qt Quick 与 QML语言(初学笔记1)

    Qt Quick Qt Quick是一些新的UI技术的集合,用来帮助开发者创建一种现在越来越多用于手机.多媒体播放器.机顶盒以及其他便携式设备上的直观的.现代的.流畅的用户界面.简单来说,Qt Qui ...

  6. jQuery慢慢啃之文档处理(五)

    1.append(content|fn)//向每个匹配的元素内部追加内容. $("p").append("<b>Hello</b>"); ...

  7. Android App 性能评测与调优

    要点: 1. 内存优化的目的以及工具介绍 2. Android APP 内存的主要问题分析与总结 3. UI 绘制原理以及量化工具 - UI 流畅度的主要问题分析以及 UI 绘制原理. 4. 如何获取 ...

  8. 10条PHP高级技巧

    1.使用一个SQL注射备忘单 一个基本的原则就是,永远不要相信用户提交的数据. 另一个规则就是,在你发送或者存储数据时对它进行转义(escape). 可以总结为:filter input, escap ...

  9. 关于ueditor1.4.3版复制section标签丢失class和style样式问题

    在复制微信的文章格式到ueditor时发现section标签中的style和class属性丢失,严重影响美观. 原文格式,排版清晰段落分明赏心悦目: 复制到ueditor后的格式...这跟原文是没法比 ...

  10. beego路由实现原理

    树形结构+递归算法实现路由的注册与匹配: 1 数据结构: // 树节点结构type Tree struct { //search fix route first fixrouters map[stri ...