生命游戏(c语言)

1968年,剑桥大学英国数学家John Horton Conway发明了一个生命游戏。一个二维矩形的M*N网格世界,这个世界中的每个方格中住着一个活着的细胞或死了的细胞。一个细胞在下一个时刻的生死取决于相邻8个方格中活着的细胞的数量。如果相邻方格中活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;相反,如果周围的活细胞过少,这个细胞会因为太孤单而死去。游戏的规则就是:当一个方格周围有2或3个活细胞时,方格中状态不变;当一个方格周围有3个活细胞时,即使这个时刻方格中没有活细胞,在下一个时刻也会诞生一个活细胞。

代码贴上
#include <stdio.h>
#include <stdlib.h>
 
#define HS 20
#define LS 60
 
 
int sf_jx(void);
void du_cssj(char [][LS], const int);
void xs_shijie(char [][LS], const int);
void js_weilai(char [][LS], const int);
void cb_shijie(char [][LS], char [][LS], const int);
int js_ljsm(const int, const int, char [][LS], const int);
 
 
int main()
{
    char shijie[HS][LS];
 
    //load data
    du_cssj(shijie, sizeof shijie / sizeof shijie[0]);
 
    do
    {
        //print the world life
        xs_shijie(shijie, sizeof shijie / sizeof shijie[0]);
        //calculate the world life
        js_weilai(shijie, sizeof shijie / sizeof shijie[0]);
    }
    while(sf_jx()); //continue?
 
    return 0;
}
 

int js_ljsm(const int gzh, const int gzl, char sj[][LS], const int sjhs)
{
    int sm = 0; // 行号
    int h, l;
 
    //3*3区域计算邻居数量
    for(h = gzh -1; h <= gzh + 1; h++)
    {
        for(l = gzl - 1; l <= gzl + 1; l++)
        {
            //边界外、负行号、负列号不考虑
            if(h < 0 || h >= sjhs)
                continue;
            if(l < 0 || l > sizeof sj[0] / sizeof sj[0][0])
                continue;
            //不考虑自身
            if(h == gzh && l == gzl)
                continue;
            if(sj[h][l] == '*')
                sm++;
        }
    }
    return sm;
}
 

void cb_shijie(char from[][LS], char to[][LS], const int hs)
{
    int h, l;
 
    for(h = 0; h < hs; h++)
        for(l = 0; l < sizeof from[0] / sizeof from[0][0]; l++)
            to[h][l] = from[h][l];
 
    return;
}
 

void js_weilai(char sj[][LS], const int hs)
{
    char dqsj[HS][LS];
 
    cb_shijie(sj, dqsj, hs);
 
    {
        int h, l;
        for(h = 0; h < hs; h++)
        {
            for(l = 0; l < sizeof sj[0] / sizeof sj[0][0]; l++)
            {
                int ljsm;
                ljsm = js_ljsm(h, l, dqsj, sizeof dqsj / sizeof dqsj[0]);
                switch(ljsm)
                {
            case 2: sj[h][l] = '*'; break;
                    case 3:break;
 
                    default: sj[h][l] = ' '; break;
                }
            }
        }
    }
    return;
}
 

void xs_shijie(char sj[][LS], const int hs)
{
    int h, l;
    system("clear");
    for(h = 0; h < hs; h++)
    {
        for(l = 0; l < sizeof sj[0] / sizeof sj[0][0]; l++)
        {
            putchar(sj[h][l]);
        }
        putchar('\n');
    }
    putchar('\n');
    putchar('\n');
}
 

void du_cssj(char sj[][LS], const int hs)
{
    int h, l;
    FILE *pf;
    if((pf = fopen("life.txt", "r")) == NULL)
        {
            printf("file load error!\n");
        }
 
    for(h = 0; h < hs; h++)
    {
        for(l = 0; l < sizeof sj[0] / sizeof sj[0][0]; l++)
        {
            char c;
            c = fgetc(pf);
            sj[h][l] = (c == '*')? ('*') : (' ') ;
        }
        fgetc(pf);
    }
    fclose(pf);
    return;
}
 

int sf_jx(void)
{
    printf("Do you want to continue ? (press Enter!)\n");
    return ( getchar() == '\n' ) ? 1 : 0;
}


其中life.txt格式为:
1234567**012345678901234***8901234567890**3456**9****4567890
12345678*012345678901234567890123456789*1*345678901*********
12*4567**012345678901234***890123456789*10345678901234567890
*****67890123******0123456*890123456789***3456************90
1*3*567**012345678901234***89*********9*1*345678901234567890
12*456789012345678901234*67890123456789***345678901234567890
1234567**012345678901234***8******56789*1*34***8901234567890
1234567*901234567890123456*890123456789*1*345678901234567890
*****678*012345678901234***890123456789***3456789********890
1234567**012345678901234*6*890123456789*1*345678901234567890
12345678*01234567890123456*890123456789***3456789012345***90
1**4567**012345678901234***890**3456789*1*3456789012345678*0
123456789012345678901234*67890123456789*1*34567890******7890
1234567**012345678901234***890123456789*1*345678901234567890
1234567*9012345678901234**7890123456*789**3456789******67890
12345678*012345678901234*6*890123456789***345678901234567890
1234567*9012345678901234*67890123456789*123456***012345**890
1234567**012345678901234*6*890123456789*1*345678901234567890
12345678*012345678901234*6*890123456789*123*****************
1234567*9012345678901234*6*8901234567890**345678901234567890


### 使用C语言实现康威的生命游戏 以下是基于康威生命游戏规则的一个简单C语言实现。该程序通过二维数组模拟细胞网格,并根据每一代的状态更新下一代。 #### 生命游戏的核心逻辑 生命游戏遵循以下规则[^1]: 1. 如果一个活细胞周围有少于两个活邻居,则它会因为孤独而死亡。 2. 如果一个活细胞周围有两个或三个活邻居,则它保持存活到下一代。 3. 如果一个活细胞周围多于三个活邻居,则它因过度拥挤而死亡。 4. 如果一个死细胞周围正好有三个活邻居,则它复活成为活细胞。 这些规则可以通过遍历整个网格并计算每个单元格周围的邻居状态来实现。 ```c #include <stdio.h> #include <stdlib.h> #define ROWS 20 #define COLS 20 // 打印当前网格状态 void print_grid(int grid[ROWS][COLS]) { for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { printf("%d ", grid[i][j]); } printf("\n"); } } // 计算某个位置的活邻居数量 int count_neighbors(int grid[ROWS][COLS], int row, int col) { int count = 0; for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { if (!(i == 0 && j == 0)) { // 跳过自己 int r = row + i; int c = col + j; if (r >= 0 && r < ROWS && c >= 0 && c < COLS && grid[r][c] == 1) { count++; } } } } return count; } // 更新网格状态至下一代 void update_grid(int current_gen[ROWS][COLS], int next_gen[ROWS][COLS]) { for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { int neighbors = count_neighbors(current_gen, i, j); if (current_gen[i][j] == 1 && (neighbors < 2 || neighbors > 3)) { next_gen[i][j] = 0; // 死亡 } else if (current_gen[i][j] == 0 && neighbors == 3) { next_gen[i][j] = 1; // 复活 } else { next_gen[i][j] = current_gen[i][j]; // 维持原状 } } } } int main() { int grid[ROWS][COLS]; // 初始化随机网格 srand(time(0)); for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { grid[i][j] = rand() % 2; // 随机初始化为0或1 } } int generations = 10; // 运行代数 while (generations--) { int new_grid[ROWS][COLS]; // 更新网格 update_grid(grid, new_grid); // 输出当前世代 system("clear"); // 清屏命令,适用于Linux/MacOS;Windows下可替换为system("cls"); print_grid(new_grid); // 延迟显示效果 sleep(1); // 将新网格赋值给旧网格 for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { grid[i][j] = new_grid[i][j]; } } } return 0; } ``` 上述代码实现了基本的生命游戏功能,包括打印网格、计数邻居以及更新网格状态的功能。 ### 关键点解释 - **`count_neighbors` 函数**: 它用于统计某一个单元格周围的八个方向上的活细胞数目。 - **`update_grid` 函数**: 根据当前代的状态和规则生成下一代表态。 - **清屏延迟**: `system("clear")` 和 `sleep(1)` 提供了动态展示的效果,便于观察每一代表态的变化。 此实现可以作为基础版本进一步扩展,比如增加用户交互界面或者优化性能[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值