Игра жизни Конвея помогает мне понять этот неожиданный результат - PullRequest
0 голосов
/ 29 сентября 2019

Мне нужна помощь в понимании того, почему моя программа печатает сетку из

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

. Правильный вывод будет таким:

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

Способ, который я написал, - создатькопия старого состояния и манипулирование им с использованием правил игры. После того, как я проверил каждую ячейку, я запоминаю количество соседей, живущих для этой ячейки. Если счет больше 3 или меньше двух, клетка умрет.

Если ячейка насчитывает 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 голосов
/ 30 сентября 2019

Функция 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
}

Live (каламбур), здесь .

...