C++实现生命细胞机,高斯帕滑翔机枪的实现以及模拟细胞分裂

播种者
相信不少接触过C语言编成的同学都了解过“生命细胞机”这么一个有意思的游戏。这个游戏由英国数学家约翰·何顿·康威在1970年发明。上图所示即为生命细胞机一个非常经典的结构:“播种者”,他有很多个高斯帕滑翔机枪组成并且一直平移,所经过之处会产生许多个高斯帕滑翔机枪不断生成高斯帕滑翔机。

生命游戏中,对于任意细胞,规则如下

  1. 每个细胞有两种状态 - 存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动
  2. 当前细胞为存活状态时,当周围的存活细胞低于2个时(不包含2个),该细胞变成死亡状态。(模拟生命数量稀少)
  3. 当前细胞为存活状态时,当周围有2个或3个存活细胞时,该细胞保持原样。
  4. 当前细胞为存活状态时,当周围有超过3个存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
  5. 当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。(模拟繁殖)

可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后,可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。

下面给出生命游戏中几种经典的细胞形态
在这里插入图片描述
在这里插入图片描述

怎么使用C语言实现生命细胞机呢?

其实生命细胞机的规则很简单,我们首先需要初始化一个二位数组模拟“棋盘”布局。随后我们生成一定量的初始点,并且使用循环的方式遍历这个数组所有的点,依次判断他们周边点的状态,从而确定下一次周期该点的生存或者死亡。

我们先给出实现代码:

#include<stdio.h>
#include <unistd.h>
#include<time.h>
#include<memory.h>
#include<string>
#include <cstdlib>
using namespace std;



int life[80][240] = {0};//生命矩阵
int lifen[80][240]= {0};//中间矩阵
int mm, nn,s,times=0;
int main(){
      srand((unsigned)time(NULL));
      for (int sy = 0; sy < 80; sy++) { //全部点都初始化为活
          for (int s = 0; s < 240; s++) {
              life[sy][s] =1;
              lifen[sy][s] = 1;
          }
      }
     /*这里可以生成随机的生命点
      for (int ra = 0; ra < 800; ra++) {
            
            mm = (rand()%80);
            nn= (rand() % 240);
            life[mm][nn] = 1;
            lifen[mm][nn] = 1;
      }*/
    int m,t,e;
    while(1){

        for(int y=1;y<79;y++)
        {//对所有的数据点进行遍历
            for(int x=1;x<239;x++)
            {
                if(life[y][x]==1)
                {    
                    m=0;
                    m = life[y - 1][x - 1] + life[y - 1][x] + life[y - 1][x + 1] + life[y][x - 1] + life[y][x + 1] + life[y + 1][x - 1] + life[y + 1][x + 1] + life[y + 1][x];//统计周围点的生存状态
                    if(m==2){
                        lifen[y][x]=1;
                    }
                    else if(m==3){
                        lifen[y][x]=1;
                    }
                    else lifen[y][x]=0;
                }
                if (life[y][x] == 0)
                {
                    m = 0;
                    m = life[y - 1][x - 1] + life[y - 1][x] + life[y - 1][x + 1] + life[y][x - 1] + life[y][x + 1] + life[y + 1][x - 1] + life[y + 1][x +1] + life[y + 1][x];

                    if (m == 3) {
                        lifen[y][x] = 1;
                    }
                    else lifen[y][x] = 0;
                }
            }
        }
        for(int my=0;my<80;my++)
        {
            for(int mx=0;mx<240;mx++)
            {
                life[my][mx]=lifen[my][mx];//将中间的矩阵状态复制给生命矩阵
            }
        }
            
            printf("start print:%d\n",times);
            for (int py = 0; py < 80; py++)
            {
                for (int px = 0; px < 240; px++)
                {
                    if (life[py][px] == 0) {
                        printf("\033[47m*\033[0m");//点死亡为白色
                    }
                    else {
                        printf("\033[41m*\033[0m");//点存活为红色
                    }
                }
                printf("\n");
            }
            usleep(100000);//每一次刷新停留0.1秒
            system("clear");
        times++;
    }
}

这段代码的执行效果如图:

在这里插入图片描述
程序在执行一段时间后会到达稳态,如图所示:
在这里插入图片描述

高斯帕滑翔机枪

那么实现了生命细胞机的基本结构,我们怎么生成震撼的滑翔机呢?
这就要求我们具有恰当的初始化的种子,这需要符合高斯帕滑翔机枪的初始结构,在这里我把它们初始化为这些点:

for (int sy = 2; sy < 11; sy++) {
          for (int ss = 0; ss < 240; ss++) {
              s=ss/40;
              s=s*40;
              if(sy==2){life[sy][s+4]=1;life[sy][s+10]=1;life[sy][s+11]=1;}
              else if(sy==3){life[sy][s+2]=1;life[sy][s+6]=1;life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+12]=1;}
              else if(sy==4){life[sy][s+6]=1;life[sy][s+12]=1;life[sy][s+13]=1;life[sy][s+15]=1;life[sy][s+24]=1;}
              else if(sy==5){life[sy][s+1]=1;life[sy][s+7]=1;life[sy][s+12]=1;life[sy][s+15]=1;life[sy][s+22]=1;life[sy][s+24]=1;}
              else if(sy==6){life[sy][s+1]=1;life[sy][s+2]=1;life[sy][s+12]=1;life[sy][s+13]=1;life[sy][s+15]=1;life[sy][s+21]=1;life[sy][s+23]=1;}
              else if(sy==7){life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+12]=1;life[sy][s+20]=1;life[sy][s+23]=1;life[sy][s+35]=1;life[sy][s+36]=1;}
              else if(sy==8){life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+21]=1;life[sy][s+23]=1;life[sy][s+35]=1;life[sy][s+36]=1;}
              else if(sy==9){life[sy][s+22]=1;life[sy][s+24]=1;}
              else if(sy==10){life[sy][s+24]=1;}
          }
      }

接下来给出完整代码:

#include<stdio.h>
#include <unistd.h>
#include<time.h>
#include<memory.h>
#include<string>
#include <cstdlib>
using namespace std;



int life[80][240] = {0};
int lifen[80][240]= {0};
int mm, nn,s,times=0;
int main(){
      for (int sj = 0; sj < 80; sj++) {
          for (int sm = 0; sm < 240; sm++) {
              life[sj][sm] =0;
              lifen[sj][sm] = 0;
          }
      }
      
      for (int sy = 2; sy < 11; sy++) {
          for (int ss = 0; ss < 240; ss++) {
              s=ss/40;
              s=s*40;
              if(sy==2){life[sy][s+4]=1;life[sy][s+10]=1;life[sy][s+11]=1;}
              else if(sy==3){life[sy][s+2]=1;life[sy][s+6]=1;life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+12]=1;}
              else if(sy==4){life[sy][s+6]=1;life[sy][s+12]=1;life[sy][s+13]=1;life[sy][s+15]=1;life[sy][s+24]=1;}
              else if(sy==5){life[sy][s+1]=1;life[sy][s+7]=1;life[sy][s+12]=1;life[sy][s+15]=1;life[sy][s+22]=1;life[sy][s+24]=1;}
              else if(sy==6){life[sy][s+1]=1;life[sy][s+2]=1;life[sy][s+12]=1;life[sy][s+13]=1;life[sy][s+15]=1;life[sy][s+21]=1;life[sy][s+23]=1;}
              else if(sy==7){life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+12]=1;life[sy][s+20]=1;life[sy][s+23]=1;life[sy][s+35]=1;life[sy][s+36]=1;}
              else if(sy==8){life[sy][s+10]=1;life[sy][s+11]=1;life[sy][s+21]=1;life[sy][s+23]=1;life[sy][s+35]=1;life[sy][s+36]=1;}
              else if(sy==9){life[sy][s+22]=1;life[sy][s+24]=1;}
              else if(sy==10){life[sy][s+24]=1;}
          }
      }
    int m,t,e;
    while(1){

        for(int y=1;y<79;y++)
        {
            for(int x=1;x<239;x++)
            {
                if(life[y][x]==1)
                {    
                    m=0;
                    m = life[y - 1][x - 1] + life[y - 1][x] + life[y - 1][x + 1] + life[y][x - 1] + life[y][x + 1] + life[y + 1][x - 1] + life[y + 1][x + 1] + life[y + 1][x];
                    if(m==2){
                        lifen[y][x]=1;
                    }
                    else if(m==3){
                        lifen[y][x]=1;
                    }
                    else lifen[y][x]=0;
                }
                if (life[y][x] == 0)
                {
                    m = 0;
                    m = life[y - 1][x - 1] + life[y - 1][x] + life[y - 1][x + 1] + life[y][x - 1] + life[y][x + 1] + life[y + 1][x - 1] + life[y + 1][x +1] + life[y + 1][x];

                    if (m == 3) {
                        lifen[y][x] = 1;
                    }
                    else lifen[y][x] = 0;
                }
            }
        }
        for(int my=0;my<80;my++)
        {
            for(int mx=0;mx<240;mx++)
            {
                life[my][mx]=lifen[my][mx];
            }
        }
        //if (times %==1) {
            
            printf("start print:%d\n",times);
            for (int py = 0; py < 80; py++)
            {
                for (int px = 0; px < 240; px++)
                {
                    if (life[py][px] == 0) {
                        //color(7);
                        printf("\033[47m*\033[0m");
                        //color(1);
                    }
                    else {
                        //color(1);
                        printf("\033[41m*\033[0m");
                        //color(7);
                    }
                }
                printf("\n");
            }
            usleep(100000);
            system("clear");
        //}
        times++;
    }
}

运行结果:
在这里插入图片描述

模拟细胞分裂

如果我们对康威的生命规则进行一些改变:

  1. 生命不会凭空产生,旧的生命可以制造新的生命。
  2. 由于环境绕动,生命可能发生位置上的移动。
  3. 生命会在一定的周期后消亡,并且生命害怕拥挤
  4. 生命不害怕孤独。

那么根据上面的规则我们修改代码如下:

#include<stdio.h>
#include <unistd.h>
#include<time.h>
#include<memory.h>
#include<string>
#include <cstdlib>
using namespace std;



int life[80][400];
int lifen[80][400];
int lifes[80][400];
int period[80][400];
int mm, nn,s,times=0,ry,rx;
int main(){
      for (int sj = 0; sj < 80; sj++) {//初始化所有生命为死亡
          for (int sm = 0; sm < 400; sm++) {
              life[sj][sm] =0;
              lifen[sj][sm] = 0;
              lifes[sj][sm] = 0;
              period[80][400];
          }
      }
      life[40][120]=1;period[40][120]=5;lifes[40][120]=1;//再一个点初始化一个生命
      srand((unsigned)time(NULL));
    int m,t,e;
    while(1){

            if(life[ry=rand()%80][rx=rand()%400]==1){//生命会随机的发生位移
               life[ry][rx]==0;
               life[ry=rand()%80][rx=rand()%400]=1;period[ry][rx]=5;lifes[ry][rx]=1;
            }
        for(int y=1;y<79;y++)
        {//开始遍历数组
            for(int x=1;x<399;x++)
            {
                if(life[y][x]==1)
                {    
                    m=0;
                    m = life[y - 1][x - 1] + life[y - 1][x] + life[y - 1][x + 1] + life[y][x - 1] + life[y][x + 1] + life[y + 1][x - 1] + life[y + 1][x + 1] + life[y + 1][x];
                    if(m==0){
                        lifen[y][x]=1;
                    }
                    else if(m==1){
                        lifen[y][x]=1;
                    }
                    else if(m==2){
                        lifen[y][x]=1;
                    }
                    else {lifen[y][x]=0;period[y][x]==0;}
                    
                    if(period[y][x]!=0)
                       period[y][x]=period[y][x]-1;//生命周期减少
                    else if(period[y][x]==0)lifen[y][x] = 0;
                }
                else if (life[y][x] == 0)
                {
                    m = 0;
                    mm=(rand()%2);
                    if(mm==1){
                    m = lifes[y - 1][x - 1] + lifes[y - 1][x] + lifes[y - 1][x + 1] + lifes[y][x - 1] + lifes[y][x + 1] + lifes[y + 1][x - 1] + lifes[y + 1][x +1] + lifes[y + 1][x];
                    if(lifes[y - 1][x - 1]==1)lifes[y - 1][x - 1]=0;
                    else if(lifes[y - 1][x]==1)lifes[y - 1][x]=0;
                    else if(lifes[y - 1][x+1]==1)lifes[y - 1][x+1]=0;
                    else if(lifes[y][x-1]==1)lifes[y][x-1]=0;
                    else if(lifes[y][x+1]==1)lifes[y][x+1]=0;
                    else if(lifes[y+1][x-1]==1)lifes[y + 1][x-1]=0;
                    else if(lifes[y+1][x]==1)lifes[y + 1][x]=0;
                    else if(lifes[y+1][x+1]==1)lifes[y + 1][x+1]=0;
                    }
                    if (m != 0) {
                        lifen[y][x] = 1;period[y][x]=5;//新生命诞生,初始化生命周期
                    }
                    else {lifen[y][x]=0;period[y][x]==0;}
                }
            }
        }

        for(int my=0;my<80;my++)
        {
            for(int mx=0;mx<400;mx++)
            {
                life[my][mx]=lifen[my][mx];
                lifes[my][mx]=lifen[my][mx];
            }
        }
            printf("start print:%d\n",times);
            for (int py = 0; py < 80; py++)
            {
                for (int px = 0; px < 400; px++)
                {
                    if (life[py][px] == 0) {
                        printf("\033[47m*\033[0m");
                    }
                    else {
                        printf("\033[41m*\033[0m");
                    }
                }
                printf("\n");
            }
            usleep(300000);
            system("clear");
        times++;
    }
}

最后来看看效果图吧:
在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值