康威(Conway)的《人生游戏》可帮助我理解这种意外的结果

时间:2019-09-29 16:56:44

标签: c++ conways-game-of-life

我想对我的程序为什么要打印网格的一些信息有所帮助

....................
....................
....................
....................
....................
...............OOOOO
OOOOOOOOOOOOO.......
....................
....................
....................

正确的输出应为:

....................
....................
....................
....................
....................
....................
....................
.............O.O....
..............OO....
..............O..... 

我编写它的方式是创建旧状态的副本并使用游戏规则对其进行操作。在检查完每个单元之后,我会存储该单元的存活邻居数。如果计数大于3或小于2,则该单元将死亡。

如果一个小区中有2个或3个邻居,则它仍处于活动状态。 如果一个死细胞的计数为3,则它变为活细胞。 这些规则将直接应用于副本版本,而不是旧版本,然后打印副本。

我尝试使用调试器,但仍不确定如何正确使用它。到目前为止,我还没有发现任何危险信号。 这是我的代码:

#include <iostream>
#include <vector>
using std::vector;
using std::cout;
vector<vector<bool> > world = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};

void generate(const vector<vector<bool> >&g,vector<vector<bool> >&newworld)
{
    int count = 0;
    newworld = g;
    for(size_t i = 0; i < g.size();i++) {
        for(size_t j = 0; j < g[i].size();j++) {
            int x = g.size(); //I rows
            int y = g[i].size(); //J columns
            //wrap the edges with formula (x+n)%n  where n = NumOfRows or NumOfCol
            if(g[(((i+1)+x)%x)][(((j-1)+y)%y)]==true){//top left
            count++;
            }
             else if(g[(((i+1)+x)%x)][j]==true){//top middle
            count++;
            }
             else if(g[(((i+1)+x)%x)][(((j+1)+y)%y)]==true){//top right
            count++;
            }
             else if(g[i][(((j-1)+y)%y)]==true){//left cell
            count++;
            }
             else if(g[i][(((j+1)+y)%y)]==true){//right cell
            count++;
            }
             else if(g[(((i-1)+x)%x)][(((j-1)+y)%y)]==true){ //bottom left
            count++;
            }
             else if(g[(((i-1)+x)%x)][j]==true){//bottom middle
            count++;
            }
             else if(g[(((i-1)+x)%x)][(((j+1)+y)%y)]==true){//bottom right
            count++;
            }

        if (g[i][j]) {
            if(count > 3 || count < 2) {//if alive cell has more than 3 or less than 2, die
            newworld[i][j] = false;
            }
            else if (count == 2 || count == 3) { //remain the same 
                newworld[i][j] = g[i][j];
            }
        }
        else if (g[i][j] == false) {//dead come alive
        if(count == 3) {
        newworld[i][j] = true;
        }

            }
        }
    }
}

void display(vector<vector<bool> >&a)
{
    for(size_t row = 0; row <a.size(); row++) {
        for(size_t column = 0; column <a[row].size(); column++){
            if (a[row][column]) {
                cout << 'O';
            }
             else {
                cout << '.';
             }
        }
        cout << '\n';
    }          
}        

int main()
{
    vector<vector<bool> > newworld;
    generate(world,newworld);
    display(newworld);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

函数generate有(至少)两个问题。

  • count在嵌套循环的外部 进行了初始化,因此它永远不会重置为零(每个单元都应该重置为零)并保持增长。

  • 所有条件都是互斥的,因此只要满足一个条件,其他条件就会被跳过。不应该有else if,而应该只有if

保留选择的数据结构,您可以将该函数重写为

using gof_t = std::vector<std::vector<bool>>;

void generate(gof_t& g, gof_t& newworld)
{
    for(size_t i = 0, x = g.size(); i < x; i++)
    {
        for(size_t j = 0, y = g[i].size(); j < y; j++)
        {
            size_t i_prev = (i + x - 1) % x;
            size_t i_next = (i + 1) % x;
            size_t j_prev = (j + y - 1) % y;
            size_t j_next = (j + 1) % y;

            int count = g[i_prev][j_prev] + g[i_prev][j] + g[i_prev][j_next]
                      + g[i     ][j_prev]                + g[i     ][j_next]
                      + g[i_next][j_prev] + g[i_next][j] + g[i_next][j_next];

            newworld[i][j] = g[i][j] ? (count == 2 || count == 3) : (count == 3);
        }
    }
    std::swap(g, newworld); // <-- Passing by non const reference, we can swap without copying
}

现场直播(双关语意味),here