首页 > 代码库 > 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语言练习题一道——生命游戏
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。