The game of life(生命游戏)新算法

我写了一种常见的实现算法,和另一种新算法,即不是每次循环计算每个细胞的周围细胞数来产生下一时刻,而是每次每个产生状态变化的细胞主动通知周围的邻居,因此每个细胞增加一个用来记录邻居数的字段。由邻居数决定每个细胞的出生和死亡,然后影响周围邻居的邻居数。并且为了不影响后续细胞的判断,需要新旧邻居数两个状态,用旧邻居数决定自己生死,而自己的生死变化影响周围邻居的新邻居数。另外如果某个格子的新旧邻居数不变则状态不变,增加一个changed字段来表示。
下面分别是旧、新两种算法。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3     
 4 #define ROW 20
 5 #define COL 60
 6 #define FILEPATH "1.txt"
 7     
 8     
 9 int countNbor(char data[][COL],int i,int j);
10 void world(void);
11     
12     
13 int main(void)
14 {
15     world();
16     return 0;
17 }
18     
19 void world(void)
20 {
21     int i,j;
22     char data[ROW][COL];
23     char temp[ROW][COL];
24     int time=0;
25     
26     
27     FILE *fp=fopen(FILEPATH,"r");
28     
29     for(i=0;i<ROW;i++)
30     {
31         for(j=0;j<COL;j++)
32         {
33             if(fgetc(fp)=='*')  //表示细胞的字符
34                 temp[i][j]=data[i][j]='*';
35             else temp[i][j]=data[i][j]=' ';
36         }
37         fgetc(fp);
38     }
39     fclose(fp);
40         
41     while(1)
42     {
43         time++;
44     
45         system("CLS");
46         for(i=0;i<ROW;i++)
47         {
48             for(j=0;j<COL;j++)
49                 printf("%c",data[i][j]);
50             printf("\n");
51         }
52         printf("次数:%d\n",time);
53     
54         system("PAUSE>NUL");
55     
56         for(i=0;i<ROW;i++)
57             for(j=0;j<COL;j++)
58                 switch(countNbor(temp,i,j))
59                 {
60                 case 3:
61                     data[i][j]='*';
62                     break;
63                 case 2:
64                     break;
65                 default:
66                     data[i][j]=' ';
67                     break;
68                 }
69     
70         for(i=0;i<ROW;i++)
71             for(j=0;j<COL;j++)
72                 temp[i][j]=data[i][j];
73     }
74     
75 }
76     
77 int countNbor(char data[][COL],int i,int j)
78 {
79     int m,n;
80     int count=0;
81     
82     for(m=i-1;m<=i+1;m++)
83         for(n=j-1;n<=j+1;n++)
84             if( (m==i&&n==j) ||m<0||n<0||m==ROW||n==COL)
85                 continue;
86             else if(data[m][n]=='*') count++;
87     
88     return count;
89 }
old.c
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3     
  4     
  5 #define ROW 20
  6 #define COL 60
  7 #define FILEPATH "1.txt"
  8     
  9     
 10 typedef struct{
 11     int live;       //1、0表生死
 12     int nbor_old;   //旧邻居数,用于判断细胞生死
 13     int nbor_new;   //新邻居数,用于下一时刻
 14     int changed;    //邻居数是否变化
 15 }Cell;
 16     
 17 typedef struct{
 18     Cell cell[ROW+2][COL+2];    //+2留边
 19     int lives_num;      //细胞数目
 20     int time_count;     //第几轮
 21 }World;
 22     
 23 void showWorld(World *world);
 24 void sendNbor(Cell cell[][COL+2],int i,int j,int live);
 25 void processCell(World *world,int i,int j);
 26 void iniWorld(World *world);
 27 void runWorld(void);
 28     
 29     
 30 int main(void)
 31 {
 32     runWorld();
 33     return 0;
 34 }
 35     
 36     
 37 void runWorld(void)
 38 {
 39     World world;
 40     Cell (*cell)[COL+2]=world.cell;
 41     int i,j;
 42     
 43     //从文件初始化
 44     iniWorld(&world);
 45     
 46     while(1)
 47     {
 48     
 49         world.time_count++;
 50         showWorld(&world);
 51     
 52         //前提 cell[i][j].nbor_old==cell[i][j].nbor_new
 53         //邻居数不变则状态不变,不用处理
 54         for(i=1;i<=ROW;i++)
 55             for(j=1;j<=COL;j++)
 56                 if(cell[i][j].changed)
 57                     processCell(&world,i,j);    //判断自身,影响周围
 58             
 59         for(i=1;i<=ROW;i++)
 60             for(j=1;j<=COL;j++)
 61                 if(cell[i][j].nbor_old==cell[i][j].nbor_new)
 62                     cell[i][j].changed=0;
 63                 else
 64                 {
 65                     cell[i][j].changed=1;
 66                     cell[i][j].nbor_old=cell[i][j].nbor_new;
 67                 }
 68     
 69     }
 70 }
 71     
 72     
 73     
 74 void iniWorld(World *world)
 75 {
 76     int i,j;
 77     FILE *fp=fopen(FILEPATH,"r");
 78     Cell (*cell)[COL+2]=world->cell;
 79     
 80     
 81     world->time_count=0;
 82     world->lives_num=0;
 83         
 84     for(i=1;i<=ROW;i++)
 85     {
 86         for(j=1;j<=COL;j++)
 87         {
 88             if(fgetc(fp)=='*')  //表示细胞的字符
 89             {
 90                 cell[i][j].live=1;
 91                 world->lives_num++;
 92             }
 93             else
 94                 cell[i][j].live=0;
 95     
 96             cell[i][j].nbor_new=cell[i][j].nbor_old=0;
 97             cell[i][j].changed=1;   //为了第一次循环每个细胞都能处理
 98         }
 99         fgetc(fp);  //换行符
100     }
101     
102     fclose(fp);
103         
104     //填充nbor_old和nbor_new
105     for(i=1;i<=ROW;i++)
106         for(j=1;j<=COL;j++)
107             if(cell[i][j].live)
108             {
109                 cell[i-1][j-1].nbor_old =++cell[i-1][j-1].nbor_new;
110                 cell[i-1][j].nbor_old   =++cell[i-1][j].nbor_new;
111                 cell[i-1][j+1].nbor_old =++cell[i-1][j+1].nbor_new;
112                 cell[i][j-1].nbor_old   =++cell[i][j-1].nbor_new;
113                 cell[i][j+1].nbor_old   =++cell[i][j+1].nbor_new;
114                 cell[i+1][j-1].nbor_old =++cell[i+1][j-1].nbor_new;
115                 cell[i+1][j].nbor_old   =++cell[i+1][j].nbor_new;
116                 cell[i+1][j+1].nbor_old =++cell[i+1][j+1].nbor_new;
117             }
118 }
119     
120     
121 //由old决定生死,并改变周围细胞的new
122 void processCell(World *world,int i,int j)
123 {
124     Cell (*cell)[COL+2]=world->cell;
125     
126     switch(cell[i][j].nbor_old)
127     {
128     case 3:
129         if(!cell[i][j].live)
130         {
131             cell[i][j].live=1;
132             sendNbor(cell,i,j,1);
133             world->lives_num++;
134         }
135         break;
136     case 2: //不变
137         break;
138     default:
139         if(cell[i][j].live)
140         {
141             cell[i][j].live=0;
142             sendNbor(cell,i,j,-1);
143             world->lives_num--;
144         }
145         break;
146     }
147 }
148     
149     
150     
151     
152 //细胞状态改变后,影响周围细胞的邻居值,live为-1或1
153 void sendNbor(Cell cell[][COL+2],int i,int j,int live)
154 {
155     cell[i-1][j-1].nbor_new+=live;
156     cell[i-1][j].nbor_new+=live;
157     cell[i-1][j+1].nbor_new+=live;
158     cell[i][j-1].nbor_new+=live;
159     cell[i][j+1].nbor_new+=live;
160     cell[i+1][j-1].nbor_new+=live;
161     cell[i+1][j].nbor_new+=live;
162     cell[i+1][j+1].nbor_new+=live;
163 }
164     
165     
166 void showWorld(World *world)
167 {
168     int i,j;
169     
170     system("CLS");
171     
172     for(i=1;i<=ROW;i++)
173     {
174         for(j=1;j<=COL;j++)
175         {
176             if(world->cell[i][j].live)
177                 printf("*");
178             else printf(" ");
179         }
180         printf("\n");
181     }
182     printf("细胞数:%d\n次数:%d\n",world->lives_num,world->time_count);
183     
184     system("PAUSE>NUL");
185 }
new.c

 

posted @ 2013-08-10 23:01  ZackCoder  阅读(1449)  评论(0编辑  收藏  举报