• The game of life(生命游戏)新算法


    我写了一种常见的实现算法,和另一种新算法,即不是每次循环计算每个细胞的周围细胞数来产生下一时刻,而是每次每个产生状态变化的细胞主动通知周围的邻居,因此每个细胞增加一个用来记录邻居数的字段。由邻居数决定每个细胞的出生和死亡,然后影响周围邻居的邻居数。并且为了不影响后续细胞的判断,需要新旧邻居数两个状态,用旧邻居数决定自己生死,而自己的生死变化影响周围邻居的新邻居数。另外如果某个格子的新旧邻居数不变则状态不变,增加一个changed字段来表示。
    下面分别是旧、新两种算法。

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3     
     4 #define ROW 20
     5 #define COL 60
     6 #define FILEPATH "1.txt"
     7     
     8     
     9 int countNbor(char data[][COL],int i,int j);
    10 void world(void);
    11     
    12     
    13 int main(void)
    14 {
    15     world();
    16     return 0;
    17 }
    18     
    19 void world(void)
    20 {
    21     int i,j;
    22     char data[ROW][COL];
    23     char temp[ROW][COL];
    24     int time=0;
    25     
    26     
    27     FILE *fp=fopen(FILEPATH,"r");
    28     
    29     for(i=0;i<ROW;i++)
    30     {
    31         for(j=0;j<COL;j++)
    32         {
    33             if(fgetc(fp)=='*')  //表示细胞的字符
    34                 temp[i][j]=data[i][j]='*';
    35             else temp[i][j]=data[i][j]=' ';
    36         }
    37         fgetc(fp);
    38     }
    39     fclose(fp);
    40         
    41     while(1)
    42     {
    43         time++;
    44     
    45         system("CLS");
    46         for(i=0;i<ROW;i++)
    47         {
    48             for(j=0;j<COL;j++)
    49                 printf("%c",data[i][j]);
    50             printf("
    ");
    51         }
    52         printf("次数:%d
    ",time);
    53     
    54         system("PAUSE>NUL");
    55     
    56         for(i=0;i<ROW;i++)
    57             for(j=0;j<COL;j++)
    58                 switch(countNbor(temp,i,j))
    59                 {
    60                 case 3:
    61                     data[i][j]='*';
    62                     break;
    63                 case 2:
    64                     break;
    65                 default:
    66                     data[i][j]=' ';
    67                     break;
    68                 }
    69     
    70         for(i=0;i<ROW;i++)
    71             for(j=0;j<COL;j++)
    72                 temp[i][j]=data[i][j];
    73     }
    74     
    75 }
    76     
    77 int countNbor(char data[][COL],int i,int j)
    78 {
    79     int m,n;
    80     int count=0;
    81     
    82     for(m=i-1;m<=i+1;m++)
    83         for(n=j-1;n<=j+1;n++)
    84             if( (m==i&&n==j) ||m<0||n<0||m==ROW||n==COL)
    85                 continue;
    86             else if(data[m][n]=='*') count++;
    87     
    88     return count;
    89 }
    old.c
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3     
      4     
      5 #define ROW 20
      6 #define COL 60
      7 #define FILEPATH "1.txt"
      8     
      9     
     10 typedef struct{
     11     int live;       //1、0表生死
     12     int nbor_old;   //旧邻居数,用于判断细胞生死
     13     int nbor_new;   //新邻居数,用于下一时刻
     14     int changed;    //邻居数是否变化
     15 }Cell;
     16     
     17 typedef struct{
     18     Cell cell[ROW+2][COL+2];    //+2留边
     19     int lives_num;      //细胞数目
     20     int time_count;     //第几轮
     21 }World;
     22     
     23 void showWorld(World *world);
     24 void sendNbor(Cell cell[][COL+2],int i,int j,int live);
     25 void processCell(World *world,int i,int j);
     26 void iniWorld(World *world);
     27 void runWorld(void);
     28     
     29     
     30 int main(void)
     31 {
     32     runWorld();
     33     return 0;
     34 }
     35     
     36     
     37 void runWorld(void)
     38 {
     39     World world;
     40     Cell (*cell)[COL+2]=world.cell;
     41     int i,j;
     42     
     43     //从文件初始化
     44     iniWorld(&world);
     45     
     46     while(1)
     47     {
     48     
     49         world.time_count++;
     50         showWorld(&world);
     51     
     52         //前提 cell[i][j].nbor_old==cell[i][j].nbor_new
     53         //邻居数不变则状态不变,不用处理
     54         for(i=1;i<=ROW;i++)
     55             for(j=1;j<=COL;j++)
     56                 if(cell[i][j].changed)
     57                     processCell(&world,i,j);    //判断自身,影响周围
     58             
     59         for(i=1;i<=ROW;i++)
     60             for(j=1;j<=COL;j++)
     61                 if(cell[i][j].nbor_old==cell[i][j].nbor_new)
     62                     cell[i][j].changed=0;
     63                 else
     64                 {
     65                     cell[i][j].changed=1;
     66                     cell[i][j].nbor_old=cell[i][j].nbor_new;
     67                 }
     68     
     69     }
     70 }
     71     
     72     
     73     
     74 void iniWorld(World *world)
     75 {
     76     int i,j;
     77     FILE *fp=fopen(FILEPATH,"r");
     78     Cell (*cell)[COL+2]=world->cell;
     79     
     80     
     81     world->time_count=0;
     82     world->lives_num=0;
     83         
     84     for(i=1;i<=ROW;i++)
     85     {
     86         for(j=1;j<=COL;j++)
     87         {
     88             if(fgetc(fp)=='*')  //表示细胞的字符
     89             {
     90                 cell[i][j].live=1;
     91                 world->lives_num++;
     92             }
     93             else
     94                 cell[i][j].live=0;
     95     
     96             cell[i][j].nbor_new=cell[i][j].nbor_old=0;
     97             cell[i][j].changed=1;   //为了第一次循环每个细胞都能处理
     98         }
     99         fgetc(fp);  //换行符
    100     }
    101     
    102     fclose(fp);
    103         
    104     //填充nbor_old和nbor_new
    105     for(i=1;i<=ROW;i++)
    106         for(j=1;j<=COL;j++)
    107             if(cell[i][j].live)
    108             {
    109                 cell[i-1][j-1].nbor_old =++cell[i-1][j-1].nbor_new;
    110                 cell[i-1][j].nbor_old   =++cell[i-1][j].nbor_new;
    111                 cell[i-1][j+1].nbor_old =++cell[i-1][j+1].nbor_new;
    112                 cell[i][j-1].nbor_old   =++cell[i][j-1].nbor_new;
    113                 cell[i][j+1].nbor_old   =++cell[i][j+1].nbor_new;
    114                 cell[i+1][j-1].nbor_old =++cell[i+1][j-1].nbor_new;
    115                 cell[i+1][j].nbor_old   =++cell[i+1][j].nbor_new;
    116                 cell[i+1][j+1].nbor_old =++cell[i+1][j+1].nbor_new;
    117             }
    118 }
    119     
    120     
    121 //由old决定生死,并改变周围细胞的new
    122 void processCell(World *world,int i,int j)
    123 {
    124     Cell (*cell)[COL+2]=world->cell;
    125     
    126     switch(cell[i][j].nbor_old)
    127     {
    128     case 3:
    129         if(!cell[i][j].live)
    130         {
    131             cell[i][j].live=1;
    132             sendNbor(cell,i,j,1);
    133             world->lives_num++;
    134         }
    135         break;
    136     case 2: //不变
    137         break;
    138     default:
    139         if(cell[i][j].live)
    140         {
    141             cell[i][j].live=0;
    142             sendNbor(cell,i,j,-1);
    143             world->lives_num--;
    144         }
    145         break;
    146     }
    147 }
    148     
    149     
    150     
    151     
    152 //细胞状态改变后,影响周围细胞的邻居值,live为-1或1
    153 void sendNbor(Cell cell[][COL+2],int i,int j,int live)
    154 {
    155     cell[i-1][j-1].nbor_new+=live;
    156     cell[i-1][j].nbor_new+=live;
    157     cell[i-1][j+1].nbor_new+=live;
    158     cell[i][j-1].nbor_new+=live;
    159     cell[i][j+1].nbor_new+=live;
    160     cell[i+1][j-1].nbor_new+=live;
    161     cell[i+1][j].nbor_new+=live;
    162     cell[i+1][j+1].nbor_new+=live;
    163 }
    164     
    165     
    166 void showWorld(World *world)
    167 {
    168     int i,j;
    169     
    170     system("CLS");
    171     
    172     for(i=1;i<=ROW;i++)
    173     {
    174         for(j=1;j<=COL;j++)
    175         {
    176             if(world->cell[i][j].live)
    177                 printf("*");
    178             else printf(" ");
    179         }
    180         printf("
    ");
    181     }
    182     printf("细胞数:%d
    次数:%d
    ",world->lives_num,world->time_count);
    183     
    184     system("PAUSE>NUL");
    185 }
    new.c
  • 相关阅读:
    CodeForces979D:Kuro and GCD and XOR and SUM(Trie树&指针&Xor)
    HDU4188:RealPhobia (连分数的运用之一)
    从HDU2588:GCD 到 HDU5514:Frogs (欧拉公式)
    SPOJ:Eagle and Dogs(求树上每个点最远可以走到哪里---树的直径||DP)
    【字符串】BZOJ上面几个AC自动机求最为字串出现次数的题目
    codeforces round #405 B. Bear and Friendship Condition
    codeforces round #419 C. Karen and Game
    codeforces round #419 B. Karen and Coffee
    codeforces round #419 A. Karen and Morning
    【ZOJ 3609】Modular Inverse 最小乘法逆元
  • 原文地址:https://www.cnblogs.com/zackcoder/p/3250836.html
Copyright © 2020-2023  润新知