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 

 67int 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语言)