康威的生命游戏 C
Conway's Game Of Life In C
我用 C 语言制作了一个康威生活游戏版本,使用的是应该环绕两侧的二维数组。不幸的是,所有发生的事情都是数字在 1 和 0 之间来回闪烁,没有清晰的模式。这是代码:
#include <stdio.h>
int main(){
int const WIDTH = 100;
int const HEIGHT = 100;
int const CYCLES = 1000;
int grid[HEIGHT][WIDTH];
int temp[HEIGHT][WIDTH];
int row;
int col;
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = 0;
}
}
int i;
int x;
int y;
int neighbours;
for(i = 0; i < CYCLES; i++){
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
temp[row][col] = 0;
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
neighbours = 0;
for(y = -1; y < 2; y++){
for(x = -1; x < 2; x++){
if(x != 0 && y != 0 && grid[(row + y) % HEIGHT][(col + x) % WIDTH] == 1){
neighbours++;
}
}
}
if(grid[row][col] == 1){
if(neighbours < 2 || neighbours > 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = temp[row][col];
printf("%d", grid[row][col]);
}
printf("\n");
}
printf("\n");
}
}
您计算邻居的方式是错误的(例如 -1%HEIGHT
呢???)。我想你想使用圆环(最左边的列连接到最右边的列,线也一样),所以你需要为边界做特殊的情况。一个技巧是使用如下的模数。
假设你有一条长度为 N
的线,然后对于从 0
到 N-1
的每个 x
,计算 mid=x+N
,将邻居作为 left=mid-1
和 right=mid+1
,然后计算 grid(left%N)
、grid(mid%N)
、grid(right%N)
的邻居(当然以相同的方式添加第二个维度)。所以你会在没有任何特殊情况的情况下捕捉环面 属性...
如果您想确保它按预期工作,我建议您将网格初始化为众所周知的 GOL 模式(例如简单的滑翔机)。
还要验证 GOL 规则是否正确。
我注意到一个问题。
第 4 条规则规定,如果一个死细胞恰好有 3 个邻居,它应该再次复活。目前,您的代码执行相反的操作
else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
如果刚好有 3 个细胞,这将使细胞死亡,如果不是这样,细胞就会存活。切换 1 和 0,它应该可以工作。
我用 C 语言制作了一个康威生活游戏版本,使用的是应该环绕两侧的二维数组。不幸的是,所有发生的事情都是数字在 1 和 0 之间来回闪烁,没有清晰的模式。这是代码:
#include <stdio.h>
int main(){
int const WIDTH = 100;
int const HEIGHT = 100;
int const CYCLES = 1000;
int grid[HEIGHT][WIDTH];
int temp[HEIGHT][WIDTH];
int row;
int col;
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = 0;
}
}
int i;
int x;
int y;
int neighbours;
for(i = 0; i < CYCLES; i++){
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
temp[row][col] = 0;
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
neighbours = 0;
for(y = -1; y < 2; y++){
for(x = -1; x < 2; x++){
if(x != 0 && y != 0 && grid[(row + y) % HEIGHT][(col + x) % WIDTH] == 1){
neighbours++;
}
}
}
if(grid[row][col] == 1){
if(neighbours < 2 || neighbours > 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = temp[row][col];
printf("%d", grid[row][col]);
}
printf("\n");
}
printf("\n");
}
}
您计算邻居的方式是错误的(例如 -1%HEIGHT
呢???)。我想你想使用圆环(最左边的列连接到最右边的列,线也一样),所以你需要为边界做特殊的情况。一个技巧是使用如下的模数。
假设你有一条长度为 N
的线,然后对于从 0
到 N-1
的每个 x
,计算 mid=x+N
,将邻居作为 left=mid-1
和 right=mid+1
,然后计算 grid(left%N)
、grid(mid%N)
、grid(right%N)
的邻居(当然以相同的方式添加第二个维度)。所以你会在没有任何特殊情况的情况下捕捉环面 属性...
如果您想确保它按预期工作,我建议您将网格初始化为众所周知的 GOL 模式(例如简单的滑翔机)。
还要验证 GOL 规则是否正确。
我注意到一个问题。
第 4 条规则规定,如果一个死细胞恰好有 3 个邻居,它应该再次复活。目前,您的代码执行相反的操作
else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
如果刚好有 3 个细胞,这将使细胞死亡,如果不是这样,细胞就会存活。切换 1 和 0,它应该可以工作。