在解决康威的《生命游戏》时。平面方法工作得很好。这种环形的方法让我很困扰。我已经检查了我的代码几个小时了,但我没有发现任何故障。我将发布两个函数,它们计算数组中每个元素的邻居数。该数组是一个结构体,有两个字段:Val(当前值)和Next(下一个值,取决于元素拥有的邻居数量)。我还应该说,每个函数对位于第一行和第一行以及第一列和最后一列的元素求值,包括边。感谢所有审阅这段代码的人,我知道这并没有那么简单。
void verifica_lin(int i,int j,int n,int m,int &cnt,matrice a[MAX][MAX]){
if(i==1){
if(j==1){
if(a[i+1][j].Val==1)
++cnt;
if(a[i+1][j+1].Val==1)
++cnt;
if(a[2][m].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
if(a[n][2].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[1][m].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
else
if(j==m){
if(a[i+1][j].Val==1)
++cnt;
if(a[1][2].Val==1)
++cnt;
if(a[i+1][j-1].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
if(a[n][m-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[1][1].Val==1)
++cnt;
}
else{
if(a[i+1][j].Val==1)
++cnt;
if(a[i+1][j+1].Val==1)
++cnt;
if(a[i+1][j-1].Val==1)
++cnt;
if(a[n][j].Val==1)
++cnt;
if(a[n][j+1].Val==1)
++cnt;
if(a[n][j-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
}
else
if(i==n){
if(j==1){
if(a[1][1].Val==1)
++cnt;
if(a[1][2].Val==1)
++cnt;
if(a[1][m].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[i-1][j+1].Val==1)
++cnt;
if(a[n-1][m].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
else
if(j==m){
if(a[1][m].Val==1)
++cnt;
if(a[1][1].Val==1)
++cnt;
if(a[1][m-1].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[n-1][m].Val==1)
++cnt;
if(a[i-1][j-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
}
else{
if(a[1][j].Val==1)
++cnt;
if(a[1][j+1].Val==1)
++cnt;
if(a[1][j-1].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[i-1][j+1].Val==1)
++cnt;
if(a[i-1][j-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
}
if(a[i][j].Val==1){
if(cnt==2||cnt==3)
a[i][j].Next=1;
else
if(cnt==0||cnt>3)
a[i][j].Next=0;
}
else
if(cnt==3)
a[i][j].Next=1;
}
void verify_col(int i,int j,int n,int m,int &cnt,matrice a[MAX][MAX]){
if(j==1){
if(i==1){
if(a[i+1][j].Val==1)
++cnt;
if(a[i+1][j+1].Val==1)
++cnt;
if(a[2][m].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
if(a[n][2].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[1][m].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
else
if(i==n){
if(a[1][1].Val==1)
++cnt;
if(a[1][2].Val==1)
++cnt;
if(a[1][m].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[i-1][j+1].Val==1)
++cnt;
if(a[n-1][m].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
else{
if(a[i+1][j].Val==1)
++cnt;
if(a[i+1][j+1].Val==1)
++cnt;
if(a[i+1][m].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[i-1][j+1].Val==1)
++cnt;
if(a[i-1][m].Val==1)
++cnt;
if(a[i][m].Val==1)
++cnt;
if(a[i][j+1].Val==1)
++cnt;
}
}
else
if(j==m){
if(i==1){
if(a[i+1][j].Val==1)
++cnt;
if(a[1][2].Val==1)
++cnt;
if(a[i+1][j-1].Val==1)
++cnt;
if(a[n][m].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
if(a[n][m-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[1][1].Val==1)
++cnt;
}
else
if(i==n){
if(a[1][m].Val==1)
++cnt;
if(a[1][1].Val==1)
++cnt;
if(a[1][m-1].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[n-1][m].Val==1)
++cnt;
if(a[i-1][j-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[n][1].Val==1)
++cnt;
}
else{
if(a[i+1][j].Val==1)
++cnt;
if(a[i+1][1].Val==1)
++cnt;
if(a[i+1][j-1].Val==1)
++cnt;
if(a[i-1][j].Val==1)
++cnt;
if(a[i-1][1].Val==1)
++cnt;
if(a[i-1][j-1].Val==1)
++cnt;
if(a[i][j-1].Val==1)
++cnt;
if(a[i][1].Val==1)
++cnt;
}
}
if(a[i][j].Val==1){
if(cnt==2||cnt==3)
a[i][j].Next=1;
else
if(cnt==0||cnt>3)
a[i][j].Next=0;
}
else
if(cnt==3)
a[i][j].Next=1;
}
环形方法类似于平面方法,但允许数组索引包裹,因此"滑翔机"将从一边消失并出现在另一边。你必须先计算想要的数组索引,然后做一个模数计算,这也适用于一个负索引。例如
index = i - 1;
index = (index + DIMENSION) % DIMENSION;
编辑:你说"我知道这不是那么简单",但只是因为你把它变得困难。你不需要所有这些不同的条件集合,所有8个邻居都可以以同样的方式完成,非常简单,例如这一行
if(a[i+1][j-1].Val == 1)
我把它改成
if( a[(i + 1) % YDIM] [(j - 1 + XDIM) % XDIM].Val == 1 )
,所以只需要8个测试,而不是您所拥有的大量不同条件。注意:你只需要在取模数之前加上DIMENSION
,这里你已经减去了。
继续,你的代码会因为所有这些分支而变慢。在添加1
之前,不需要测试单元格是否为1
。如果单元格内容是0
或1
,您需要做的就是添加它。
cnt += a[(i + 1) % YDIM] [(j - 1 + XDIM) % XDIM].Val;