康威生命游戏 - 环形方法 - 边缘和角落

conway game of life - toroidal approach - rim and corners

再次解决康威的生命游戏。平面方法工作得很好。令我非常困扰的是环形方法。几个小时以来,我一直在检查我的代码,但我找不到任何错误。我将 post 这两个函数计算数组中每个元素的邻居数。该数组是一个具有两个字段的结构: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;
}

环形方法类似于平面方法,但允许数组索引环绕,因此 "glider" 会离开一个边缘并出现在另一侧。您必须首先计算所需的数组索引,然后进行模数计算,这也适用于负索引。例如

index = i - 1;
index = (index + DIMENSION) % DIMENSION;

编辑:你说 "I know it's not that simple" 但只是因为你让它变得困难。你不需要所有那些不同的条件集,所有 8 个邻居都可以用同样的方式完成,非常简单,例如这条线

if(a[i+1][j-1].Val == 1)

我会做那个

if( a[(i + 1) % YDIM] [(j - 1 + XDIM) % XDIM].Val == 1 )

所以只需要 8 个测试,而不是您拥有的大量不同条件。注意:你只需要在取模之前添加DIMENSION,你已经减去。

继续前进,您的代码将因所有这些分支而变慢。在添加 1 之前,您不需要测试单元格是否为 1。如果单元格内容是 01,您需要做的就是添加它。

cnt += a[(i + 1) % YDIM] [(j - 1 + XDIM) % XDIM].Val;