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. 活细胞 ...
随机推荐
- ashx页面 “检测到有潜在危险的 Request.Form 值”的解决方法(控制单个处理程序不检测html标签)
如题: 使用web.config的configuration/location节点. 在configuration节点内新建一个location节点,注意这个节点和system.webserver那些 ...
- power desinger 学习笔记<六>
原帖地址:http://blog.csdn.net/spt110/article/details/8640849 PowerDesigner中Table视图同时显示Code和Name,像下图这样的效果 ...
- framework not found -fno-arc编译错误
由于我是刚接手的代码 然后我拿来运行根本就是运行不了的 然后需要在linker 那边删除点东西就可以了. 把下边的两个删除就可以了 关于other linker flags 的介绍 请参考http ...
- 移动触摸事件(touchstart、touchmove和touchend)
touchstart事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发. touchmove事件:当手指在屏幕上滑动的时候连续地触发.在这个事件发生期间,调用preventDefaul ...
- 【HDU4366】【DFS序+分块】Successor
Problem Description Sean owns a company and he is the BOSS.The other Staff has one Superior.every st ...
- js作用域与作用域链
一直对Js的作用域有点迷糊,今天偶然读到JavaScript权威指南,立马被吸引住了,写的真不错.我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫. 一:函数作用 ...
- eclipse中show whitespace characters显示代码空格,TAB,回车 导致代码乱恶心
Eclipse中show whitespace characters显示回车.空格符. 取消此功能的第二种方式:
- Java包详解
背景: 在java中要求文件名和类名相同,所以如果把多个类放在一起,就可能出现文件名冲突 所以用包来解决,一个包中可以包含多个类 包是java提供的一种用于区别类的名字空间的机制,是类的组织方式,是一 ...
- 编译内核出错:invalid option `abi=aapcs-linux' 解决办法
出现此问题的原因是由于kernel feature中选中了Use the ARM EABIto compile the kernel引起的,有两各解决办法: 1)换编译器为arm-linux-gcc ...
- IOS--UITextFiled的使用方法
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for ...