细胞自动机(又称元胞自动机),名字虽然很深奥,但是它的行为却是非常美妙的。所有这些怎样实现的呢?我们可以把计算机中的宇宙想象成是一堆方格子构成的封闭空间,尺寸为N的空间就有N*N个格子。而每一个格子都可以看成是一个生命体,每个生命都有生和死两种状态,如果该格子生就显示蓝色,死则显示白色。每一个格子旁边都有邻居格子存在,如果我们把3*3的9个格子构成的正方形看成一个基本单位的话,那么这个正方形中心的格子的邻居就是它旁边的8个格子。
每个格子的生死遵循下面的原则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。
这样就把这些若干个格子(生命体)构成了一个复杂的动态世界。运用简单的3条作用规则构成的群体会涌现出很多意想不到的复杂性为,这就是复杂性科学的研究焦点。
使用两个空间轮流作为生活空间和上一个时间的快照。
1 #include <stdbool.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 /*全局变量*/ 6 static int time = 0; 7 static int boxSize; 8 9 /*函数声明*/ 10 void playLifeGame(bool **, bool **); 11 bool printLifeBox(bool **); 12 void setLife(bool *oneLife, int x, int y, bool **snapshot); 13 14 /*主函数*/ 15 int main() { 16 while (1) { 17 printf("请输入棋盘边长:\n"); 18 scanf("%d", &boxSize); 19 if (boxSize < 3) printf("棋盘边长小于3,请重新输入\n"); 20 else break; 21 22 } 23 bool **lifeBox = (bool **) malloc(sizeof(bool *) * (boxSize + 2)); 24 bool **snapshot = (bool **) malloc(sizeof(bool *) * (boxSize + 2)); 25 26 for (int index = 0; index < boxSize + 2; index++) { 27 lifeBox[index] = (bool *) malloc(sizeof(bool) * (boxSize + 2)); 28 snapshot[index] = (bool *) malloc(sizeof(bool) * (boxSize + 2)); 29 } 30 31 for (int x = 0; x < boxSize + 2; x++) //让边界视为一个个死亡的有机体 32 { 33 lifeBox[0][x] = false; 34 lifeBox[x][0] = false; 35 lifeBox[boxSize + 1][x] = false; 36 lifeBox[x][boxSize + 1] = false; 37 snapshot[0][x] = false; 38 snapshot[x][0] = false; 39 snapshot[boxSize + 1][x] = false; 40 snapshot[x][boxSize + 1] = false; 41 } 42 43 printf("请依次输入生命状态,0为死亡,其他数为活着\n"); 44 int temp; 45 for (int i = 1; i <= boxSize; i++) { 46 printf("%d行:", i); 47 for (int j = 1; j <= boxSize; j++) { 48 scanf("%d", &temp); 49 if (temp) { 50 lifeBox[i][j] = true; 51 snapshot[i][j] = true; 52 } else { 53 lifeBox[i][j] = false; 54 snapshot[i][j] = false; 55 } 56 } 57 printf("\n"); 58 } 59 getchar(); 60 printLifeBox(lifeBox); 61 bool **tmp; 62 for (; time < INT32_MAX;) { 63 if (getchar() == 'q') { 64 break; 65 } 66 tmp = lifeBox; 67 lifeBox = snapshot; 68 snapshot = tmp; 69 playLifeGame(lifeBox, snapshot); 70 printf("\n第%d次\n", ++time); 71 if (!printLifeBox(lifeBox)) { 72 printf("全部死光了\n"); 73 break; 74 } 75 } 76 return 0; 77 } 78 79 void playLifeGame(bool **lifeBox, 80 bool **snapshot) { 81 for (int iA = 1; iA <= boxSize; iA++) { 82 for (int kA = 1; kA <= boxSize; kA++) { 83 setLife(&lifeBox[iA][kA], iA, kA, snapshot); 84 } 85 } 86 } 87 88 void setLife(bool *oneLife, 89 int x, 90 int y, 91 bool **snapshot) { 92 int countLife = 0; 93 if (snapshot[x - 1][y - 1]) { countLife++; } 94 if (snapshot[x - 1][y]) { countLife++; } 95 if (snapshot[x - 1][y + 1]) { countLife++; } 96 if (snapshot[x][y - 1]) { countLife++; } 97 if (snapshot[x][y + 1]) { countLife++; } 98 if (snapshot[x + 1][y - 1]) { countLife++; } 99 if (snapshot[x + 1][y]) { countLife++; } 100 if (snapshot[x + 1][y + 1]) { countLife++; } 101 if (countLife == 3) { 102 *oneLife = true; 103 } else if (countLife != 2) { 104 *oneLife = false; 105 } 106 107 } 108 109 bool printLifeBox(bool **lifeBox) { 110 bool result = false; 111 for (int i = 1; i <= boxSize; i++) { 112 for (int index = 0; index < boxSize; index++) 113 printf("---"); 114 printf("\n"); 115 for (int j = 1; j <= boxSize; j++) { 116 printf("|"); 117 if (lifeBox[i][j]) { 118 printf("*"); 119 result = true; 120 } else { 121 printf(" "); 122 } 123 printf("|"); 124 } 125 printf("\n"); 126 } 127 for (int ind = 0; ind < boxSize; ind++) { 128 printf("---"); 129 } 130 printf("\n"); 131 return result; 132 }