首页 > 代码库 > C语言练习题一道——生命游戏

C语言练习题一道——生命游戏

生命游戏是一个很简单,但却是很有趣的程序习题。在一个四周都可以延伸到无限的

棋盘上的某个格子中会有一个有机体。每一个有机体在时间t 时,会依照环绕着它的8 个邻

居的特性而决定在时间t+1 时是否能生存下去。如果某一格在时间t 时:

(1)有一个有机体,但是它的邻居少于或等于1 个,或者是大于3 个,那就会因为不

够稠密或太过稠密,这个有机体在时间t+1 时就会死亡;换言之,在t+1 时间,那一格中不

会存在有机体。下面就是几个在时间t+1 时会死亡的例子,如图1 所示。

图1

(2)有有机体在该处,当只有2 个或3 个邻居时,就可以继续生存。

(3)如果没有有机体,而那一格恰好有3 个邻居时,当时间为t+1 时,那一格就会生

出一个有机体。

(4)其他情形不会造成新的有机体出生。

程序要输入棋盘的大小(毕竟内存有限,不能表示无限的棋盘,不是吗?),并且输入

最大的时间值,比如N,然后输入一个在开始时有机体分布情况,最后显示出时间为2,3,…,

N 时棋盘上的状态。

 

  1 /* 思路就是将每个点看成一个独立的生命(结构体),是生是死由唯一成员数据lifeTime决定   2   3 * lifeTime非0即为活,为负数即为死   4   5 * 根据条件:   6   7 * 活着的时候:当周围为稳定条件时保持0;当周围不稳定时lifeTime自增;如果大于maxAge就死亡(初始为-1);(中途稳定了也变0)   8   9 * 死亡的时候:当周围存在3条命就自减;当周围不是三个就保持-1;如果小于-maxAge-1就复活(为了非负情况)  10  11 * 按一次时间走一格。  12  13 * 另外 我将二维数组的外围根据输入棋盘大小增加了一圈,全部设置为死亡(为了好判断周围活着的生命数)  14  15 *  16  17 * 遇到的问题: 1.曾经依次打印出一个点就判断一个点的下一个状态,这很明显的不对的。因为每改动一个点都会影响下一个点。  18  19 * 所以需要用一个临时的二重数组保存当前快照。  20  21 * 由于我是用二重指针创建的,(为了动态创建数组和传参给函数,二维数组无法作为参数)  22  23 * 所以需要在快照用完后删除二重指针(虽然小程序无妨不过养成好习惯是必要的)。  24  25 * 2.在条件判断的时候忘记与和或的结合顺序而没有打括号,导致结合的时候先是后面的与结合然后再或,导致结果出现了问题。  26  27 * 3.小小的warning:刚开始我用malloc创建的空间习惯性地还是用了C++的delete[] ptr和delete[] ptr[index]来删除二维数组。后来发现这个问题才改成了free  28  29 */  30  31 #include<stdio.h>  32  33 #include<stdlib.h>  34  35 /*负数为死亡时间*/  36  37 typedef struct life{  38  39 int lifeTime;  40  41 }Life;  42  43   44  45 /*全局变量*/  46  47 int time=0;  48  49 int maxAge;  50  51 int boxSize;  52  53 /*函数声明*/  54  55 void playLifeGame(Life** LifeBox);  56  57 void printLife(Life onelife);  58  59 void setLife(Life &onelife,int xCoordinate,int yxCoordinate,Life** temp);  60  61 bool judgeIfAlive(Life onelife);  62  63   64  65 /*主函数*/  66  67 void main(){  68  69 while(1){  70  71 printf("请输入周期时间:\n");  72  73 scanf("%d",&maxAge);  74  75     if(maxAge<1) printf("生存时间小于1,请重新输入\n");  76  77     else break;  78  79     }  80  81     maxAge--;  82  83     while(1){  84  85 printf("请输入棋盘边长:\n");  86  87     scanf("%d",&boxSize);  88  89     if(boxSize<3) printf("棋盘边长小于3,请重新输入\n");  90  91     else break;  92  93     }  94  95 Life** LifeBox=(Life **)malloc(sizeof(Life*)*(boxSize+2));  96  97     for(int index=0;index<boxSize+2;index++)  98  99     { 100 101         LifeBox[index]=(Life *)malloc(sizeof(Life)*(boxSize+2)); 102 103     } 104 105     for(int x=0;x<boxSize+2;x++) //让边界视为一个个死亡的有机体 106 107     { 108 109         LifeBox[0][x].lifeTime=-1; 110 111         LifeBox[x][0].lifeTime=-1; 112 113         LifeBox[boxSize+1][x].lifeTime=-1; 114 115         LifeBox[x][boxSize+1].lifeTime=-1; 116 117     } 118 119 printf("请依次输入生命状态,0为死亡,其他数为活着\n"); 120 121 int temp; 122 123 for(int i=1;i<=boxSize;i++) 124 125 { 126 127         for(int j=1;j<=boxSize;j++) 128 129 { 130 131             printf("%d行 %d列:",i,j); 132 133             scanf("%d",&temp); 134 135 if(temp!=0) LifeBox[i][j].lifeTime=0; 136 137 else LifeBox[i][j].lifeTime=-1; 138 139             } 140 141         printf("\n"); 142 143     } 144 145 while(1) { 146 147         playLifeGame(LifeBox); 148 149     } 150 151 } 152 153 void playLifeGame(Life** LifeBox) 154 155 { 156 157     printf("\n\n第%d次\n",time++); 158 159     for(int i=1;i<=boxSize;i++) 160 161     { 162 163         for(int index=0;index<boxSize;index++) 164 165         printf("---"); 166 167         printf("\n"); 168 169         for(int j=1;j<=boxSize;j++) 170 171         { 172 173             printLife(LifeBox[i][j]); 174 175         } 176 177         printf("\n"); 178 179     } 180 181     //保存当前状态 182 183     Life** temp= (Life **)malloc(sizeof(Life*)*(boxSize+2)); 184 185     for(int index=0;index<boxSize+2;index++) 186 187     { 188 189         temp[index]=(Life *)malloc(sizeof(Life)*(boxSize+2)); 190 191     } 192 193     for(int iB=0;iB<=boxSize+1;iB++) 194 195     { 196 197         for(int kB=0;kB<=boxSize+1;kB++) 198 199         { 200 201             temp[iB][kB]=LifeBox[iB][kB]; 202 203         } 204 205     } 206 207     //到此为止 208 209     for(int iA=1;iA<=boxSize;iA++) 210 211     { 212 213         for(int kA=1;kA<=boxSize;kA++) 214 215         { 216 217             setLife(LifeBox[iA][kA],iA,kA,temp); 218 219         } 220 221     } 222 223     for(int ind=0;ind<boxSize;ind++) 224 225         printf("---"); 226 227     printf("\n"); 228 229     system("pause"); 230 231     //删除临时快照 232 233     for(int inde=0;inde<boxSize+2;inde++) 234 235         free(temp[inde]); 236 237     free(temp); 238 239 } 240 241  242 243 void printLife(Life onelife){ 244 245     printf("|"); 246 247     if(judgeIfAlive(onelife)) 248 249         printf("*"); 250 251     else printf(" "); 252 253     printf("|"); 254 255 } 256 257  258 259 void setLife(Life &onelife,int xCoordinate,int yCoordinate,Life** temp){ 260 261     int countLife=0; 262 263  264 265     if(judgeIfAlive(temp[xCoordinate-1][yCoordinate-1])) countLife++; 266 267     if(judgeIfAlive(temp[xCoordinate-1][yCoordinate])) countLife++; 268 269     if(judgeIfAlive(temp[xCoordinate-1][yCoordinate+1])) countLife++; 270 271     if(judgeIfAlive(temp[xCoordinate][yCoordinate-1])) countLife++; 272 273     if(judgeIfAlive(temp[xCoordinate][yCoordinate+1])) countLife++; 274 275     if(judgeIfAlive(temp[xCoordinate+1][yCoordinate-1])) countLife++; 276 277     if(judgeIfAlive(temp[xCoordinate+1][yCoordinate])) countLife++; 278 279     if(judgeIfAlive(temp[xCoordinate+1][yCoordinate+1])) countLife++; 280 281  282 283     if(onelife.lifeTime>maxAge-1) {onelife.lifeTime=-1;return;} 284 285     if(onelife.lifeTime<-maxAge) {onelife.lifeTime=0;return;} 286 287  288 289     if(countLife>1&&countLife<4&&onelife.lifeTime>=0) {onelife.lifeTime=0;return;} 290 291     if((countLife>3||countLife<2)&&onelife.lifeTime>=0) {onelife.lifeTime++;return;} 292 293  294 295     if(countLife==3&&onelife.lifeTime<0) {onelife.lifeTime--;return;} 296 297     if(countLife!=3&&onelife.lifeTime<0) {onelife.lifeTime=-1;return;} 298 299 } 300 301  302 303 bool judgeIfAlive(Life onelife) 304 305 { 306 307     if(onelife.lifeTime>=0) return true; 308 309     else return false; 310 311 }

 

C语言练习题一道——生命游戏