生命游戏规则:(写一段伪代码,可能更好理解)
if(细胞是活的)
? ? ? ? 1.若周围细胞数>3,这个细胞会死亡????????????????//人太多了,饿死的
? ? ? ? 2.若周围细胞数=2或者3,细胞还是活的??????????//周围的人数刚刚好,不多不少
? ? ? ? 3.若周围细胞数=0或者1,细胞会死????????????????//周围细胞太少,抑郁死的
else//细胞是死的
? ? ? ? 1. 若周围细胞数=3,这个细胞会活过来?????????????//周围的人救了它
? ? ? ? 2.其他情况,细胞仍然是死的? ? ? ? ? ? ? ? ? ? ? ? ? //周围的细胞要么太多,要么太少
以下是代码实现:
#include<stdio.h>
#include<windows.h>
#include<time.h>
#include<stdlib.h>
#define LEN 80//地图横着多长 数组的列
#define HIGH 40//地图高度 数组的行
void init_map(int map[HIGH][LEN])//输入地图的长和宽
{
for (int i = 1; i < HIGH; i++)//i控制行
{
for (int j = 1; j < LEN; j++)//j控制列
{
//map[i][j]=rand() % 2;//这样的话数组里面只有0和1了
//((i == 0) || (j==0)) ? map[i][j] = 0 : map[i][j] = rand() % 2;....这个三目表达式为什么报错,不可修改的左值?
if (i == 0 || j == 0)
{
map[i][j] = 0;
}
else
{
map[i][j] = rand() % 2;
}
}
}
}
//这其实是生命游戏的实现逻辑,也是cal_map()的主体
void is_live(int map0[HIGH][LEN],int map[HIGH][LEN],int i,int j)
{
int count = (map0[i - 1][j - 1] + map0[i - 1][j] + map0[i - 1][j + 1] + map0[i][j - 1] + map0[i][j + 1] + map0[i + 1][j - 1] + map0[i + 1][j] + map0[i + 1][j + 1]);
if (map0[i][j] == 1)//如果当前为活细胞
{
switch (count)
{
case 0:
case 1:
{
map[i][j] = 0;//周围生命太少,抑郁死了
break;
}
case 2:
case 3:
{
map[i][j] = 1;
break;//细胞状态保持不变
}
case 4:
case 5:
case 6:
case 7:
case 8:
{
map[i][j] = 0;//周围生命太多,被饿死了
break;
}
}
}
else//如果当前为死细胞
{
if (count == 3)
map[i][j] = 1;//如果周围恰好有三个细胞,那么就造了个娃。为什么是三个人造娃...
else
{
map[i][j] = 0;
}
}
}
//将map0[][]的状态判断后,将结果存在map中。也就是前面的数组计算出结果后保存在后面这个数组中。
void cal_map(int map0[HIGH][LEN],int map[HIGH][LEN] )
{
for (int i = 1; i < HIGH; i++)
{
for (int j = 1; j < LEN; j++)
{
is_live(map0,map,i,j);
}
}
}
void print_map(int map[HIGH][LEN])
{
for (int i = 0; i < HIGH; i++)
{
for (int j = 0; j < LEN; j++)
{
map[i][j] == 1 ? printf("■") : printf(" ");
}
printf("\n");
}
printf("\n");
}
int main()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取光标句柄
COORD zero = { 0,0 };
int map0[HIGH][LEN];
int map[HIGH][LEN];
srand((unsigned int)time(NULL));
init_map(map0);
print_map(map0);//打印一下初始化之后的地图
int count = 1;
while (1)
{
system("pause");
printf("演化次数:%d", count++);
cal_map(map0,map);//计算map0周围的细胞状态,然后将结果存放在map中。
SetConsoleCursorPosition(handle, zero);//将光标位置返回到最左上角
print_map(map);//打印map
system("pause");
printf("演化次数:%d", count++);
SetConsoleCursorPosition(handle, zero);//将光标位置返回到最左上角
cal_map(map, map0);//计算map周围的细胞状态,然后将结果存放在map0
print_map(map0);//打印map0
}
system("pause");
return 0;
}
这段代码看起来有点多,但如果从主函数里面的几个函数出发,很容里理清楚逻辑关系。其中最重要的是cal_map()函数,cal=calculate 计算。
其中里面有一个获取句柄操作和将光标移动到左上角位置两行代码,是用来替代清屏函数system("cls");如果这里用的是清屏函数,那么会有很明显的闪烁现象。当然,解决这个问题还有一个方法,就是利用双缓冲来解决屏幕闪烁,读者可以自行查阅。
|