康威游戏的生命-环形接近-边缘和角落



在解决康威的《生命游戏》时。平面方法工作得很好。这种环形的方法让我很困扰。我已经检查了我的代码几个小时了,但我没有发现任何故障。我将发布两个函数,它们计算数组中每个元素的邻居数。该数组是一个结构体,有两个字段: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。如果单元格内容是01,您需要做的就是添加它。

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

最新更新