Game of Life C++, проверка соседей

Я пытаюсь написать «Игру жизни» Конвея.

К сожалению, когда я иду проверять соседей блока, я всегда получаю ошибку в определенных элементах в моих массивах. В частности, в grid[0][11] он дает мне одного соседа, однако я установил его так, что я всегда добавляю значение к переменной, называемой соседями, только когда блок вокруг нее не является пробелом или ' ' в моем коде.

Я полагаю, что условия в операторах if также учитывают, чтобы он не выходил за пределы массива.

Весь массив заполнен ' ', и, несмотря на это, я все еще получаю значение для соседа.

Я был в этом в течение нескольких часов и не нашел решения. Мой код все еще изобилует попытками тестирования, и я прошу прощения за его неаккуратность. Заранее благодарю всех за любую помощь, которую вы можете оказать в решении моей проблемы.

int _tmain(int argc, _TCHAR* argv[])
{
    bool infloop = true;
    //Create the playing grid.
    char grid[HEIGHT][WIDTH];
    //Comment out later. Used for testing.
    for(int i=0; i<75; i++)
        for(int j=0; j<22; j++)
            grid[i][j] = ' ';

    //Create initial seed here. grid [x coordinate] [y coordinate].
    //grid [1][1] = '+'; grid [2][1] = '+'; grid [3][1] = '+';

    //Key. * is going to live. + is alive currently. 
    //- is going to die, and negative space is dead.

    //As Conway's Game of Life runs infinitely, create an infinite loop.
    while (infloop)
        generation(grid);


    cout << endl;
    system("pause");
    return 0;
}

void generation(char grid[][WIDTH]) {

    int neighbors;

    /*Check each point on the grid for alive or dead. If it is, check the 
    surrounding neighbors and apply the game's rules.*/
    for(int x=0; x<75; x++) {
        for(int y=0; y<22; y++)
        {

            neighbors = 0;
            /*check all eight neighbors except for when outside of the 
            array.*/
            if((grid[x+1][y] != ' ') && (grid[x+1][y] < grid[HEIGHT][y])){
                neighbors++; cout << "A";
            }

            if((grid[x-1][y] != ' ') && (grid[x-1][y] > grid[-1][y])){
                neighbors++; cout << "E";
            }

            if((grid[x][y+1] != ' ') && (grid[x][y+1] < grid[x][WIDTH])){
                neighbors++; cout << "C";
            }

            if((grid[x][y-1] != ' ') && (grid[x][y-1] > grid[x][-1])){
                neighbors++; cout << "G";
            }

            if((grid[x+1][y+1] != ' ') && (grid[x+1][y+1] < grid[HEIGHT][WIDTH])){
                neighbors++; cout << "B";
            }

            grid[0][11] = ' '; grid[11][0] = ' ';
            if((grid[x-1][y-1] != ' ') && (grid[x-1][y-1] > grid[-1][-1])){
                neighbors++; cout << "F";
            }

            if((grid[x+1][y-1] != ' ') && (grid[x+1][y] < grid[HEIGHT][y]) &&
                (grid[x][y-1] > grid[x][-1])){
                    neighbors++; cout << "H";
            }

            if((grid[x-1][y+1] != ' ') && (grid[x-1][y] > grid[-1][y])
                && (grid[x][y+1] < grid[x][WIDTH])){
                    neighbors++; cout << "D";
            }

            system("pause");

            cout << neighbors;

            //Set a marker for each point according to neighbor amounts and key.
            if(grid[x][y] == '+' && neighbors < 2)
                grid[x][y] = '-';

            if(grid[x][y] == '+' && (neighbors == 2 || neighbors == 3))
                grid[x][y] = '*';

            if(grid[x][y] == '+' && neighbors > 3)
                grid[x][y] = '-';

            if(grid[x][y] == ' ' && (neighbors == 3))
                grid[x][y] = '*';
        }
    }
    for(int x=0; x<75; x++){
        for(int y=0; y<22; y++)
        {
            if(grid[x][y] == '*')
                grid[x][y] = '+';

            if(grid[x][y] == '-')
                grid[x][y] = ' ';
        }
    }
    system("pause");
    display(grid);
}

person VDSturacov    schedule 21.02.2014    source источник


Ответы (3)


Вот простой способ проверить, живы ли соседи ячейки. Поместите следующий код в функцию и передайте строку и столбец ячейки, которую вы хотите проверить.

int live_cell_count = 0;
for (int i = -1; i <= 1; i++)
{
    for (int j = -1; j <= 1; j++)
    {
        //disregard grid[row][col]
        if (!(i == 0 && j == 0) && inBounds(row+i,col+j)
                 && grid[row+i][col+j] == '+')
              live_cell_count++;
    }
}

Обратите внимание, что bool inBounds(int, int) — это функция, которая проверяет, не уходите ли вы за пределы массива. Если бы вы работали с сеткой 40 x 30, inBounds() был бы таким простым однострочным

return ((row >= 0 && row < 40) && (col >= 0 && col < 30));

Я оставляю ОП в качестве упражнения применять правила жизни, основанные на значении live_cell_count.

person Tyler Gaona    schedule 21.02.2014

Проверка соседей в настоящее время проверяет содержимое, когда вы хотите проверить индекс. Кроме того, убедитесь, что вы проверяете индекс перед проверкой содержимого, иначе вы получите проблемы с выходом за границы массива.

Вот первое исправлено:

if ((x+1 < HEIGHT) && (grid[x+1][y] != ' ')) { // Swap and index instead of contents.
   neighbors++; cout << "A";
}
person Steven Hansen    schedule 21.02.2014

75 лучше заменить на HEIGHT, 22 заменить на WIDTH.

if((grid[x+1][y] != ' ') && (x+1 < HEIGHT)) {
        neighbors++; cout<<"A";
}

должно быть

if((x+1 < HEIGHT) && (grid[x+1][y] != ' ')) { // The range check should be done firstly
        neighbors++; cout<<"A";
}
person Charlie    schedule 21.02.2014