Логическая ошибка с Game of Life (C ++)

Я работаю над игрой жизни Конвея, и я чувствую, что очень близок к ее завершению, но в моей логике есть некоторый недостаток. Я уже часами обдумываю это и чувствую, что вторая пара глаз сможет обнаружить мою ошибку гораздо быстрее, чем я. Моя программа компилируется просто отлично, но вывод не соответствует указаниям для игры в определенных местах (например, в столбце 0, строка 1 имеет жизнь во втором поколении, когда это не должно быть, но кажется, что вся строка 10 работает должным образом). Для тех, кто незнаком:
http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules

Я почти уверен, что логическая ошибка имеет место в функции advGen. Следующая ссылка содержит содержимое дляbac.txt, которое использует функция readGrid: http://pastebin.com/6vurFRSB

Спасибо, что нашли время, чтобы прочитать и помочь, если вы решите это сделать.

    //sample setup to start the game of life - startlife.cpp

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

const int SIZE = 20;

//initial function prototypes
void initGrid(bool life[][SIZE], bool nextGen[][SIZE]);
void readGrid(bool life[][SIZE], bool nextGen[][SIZE]);
void printGrid(bool life[][SIZE], bool nextGen[][SIZE]);
void advGen(bool life[][SIZE], bool nextGen[][SIZE]);

int main()
{
bool life[SIZE][SIZE];
bool nextGen[SIZE][SIZE];

readGrid(life, nextGen);
/* for (int count = 0; count < 5; count++){
determineNextGen(life);
}*/

printGrid(life, nextGen);
advGen(life, nextGen);
printGrid(life, nextGen);

return 0;
}/*-------------------------------------------------------

readGrid (and related functions)

---------------------------------------------------------*/

void readGrid(bool life[][SIZE], bool nextGen[][SIZE])
{
ifstream infile("bacteria.txt"); //see class site project#5 for data file

int numBacteria, row, col;

initGrid(life, nextGen);

infile >> row >> col;
while (infile){
life[row][col] = true;
infile >> row >> col;
}
infile.close();
}void initGrid(bool life[][SIZE], bool nextGen[][SIZE])
{
for (int row = 0; row < SIZE; row++)
{
for (int col = 0; col < SIZE; col++){
life[row][col] = false;
}
}
for (int row = 0; row < SIZE; row++)
{
for (int col = 0; col < SIZE; col++){
nextGen[row][col] = false;
}
}
}

void printGrid(bool life[][SIZE], bool nextGen[][SIZE])
{
cout << "  01234567890123456789" << endl;
for (int row = 0; row < SIZE; row++)
{
cout << setw(2) << row;
for (int col = 0; col < SIZE; col++)
{
if (life[row][col])
{
cout << "*";
}
else
{
cout << " ";
}
}
cout << endl;
}
}

void advGen(bool life[][SIZE], bool nextGen[][SIZE])
{
int neighbor = 0;

for (int row = 0; row < SIZE; row++)
{
for (int col = 0; col < SIZE; col++)
{
if (row == 0)
{
if (col == 0)
{
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row + 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
else if (col == 19)
{
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row + 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
else
{
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row + 1][col + 1] == true)
++neighbor;
if (life[row + 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
}
if (row == 19)
{
if (col == 0)
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row - 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
else if (col == 19)
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row - 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
else
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row - 1][col - 1] == true)
++neighbor;
if (life[row - 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
}
if (col == 0)
{
if (row == 0)
{
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row + 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
//nothing
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
//nothing
}
}
else if (row == 19)
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row - 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
//nothing
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
//nothing
}
}
else
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row - 1][col + 1] == true)
++neighbor;
if (life[row + 1][col + 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
}
if (col == 19)
{
if (row == 0)
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row + 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
//nothing
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
//nothing
}
}
else if (row == 19)
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row - 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
//nothing
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
//nothing
}
}
else
{
if (life[row][col - 1] == true)
++neighbor;
if (life[row - 1][col] == true)
++neighbor;
if (life[row + 1][col] == true)
++neighbor;
if (life[row + 1][col - 1] == true)
++neighbor;
if (life[row - 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}
}
else
{
if (life[row - 1][col] == true)
++neighbor;
if (life[row + 1][col] == true)
++neighbor;
if (life[row][col - 1] == true)
++neighbor;
if (life[row][col + 1] == true)
++neighbor;
if (life[row - 1][col - 1] == true)
++neighbor;
if (life[row + 1][col + 1] == true)
++neighbor;
if (life[row - 1][col + 1] == true)
++neighbor;
if (life[row + 1][col - 1] == true)
++neighbor;
if ( (life[row][col] == true) && (neighbor < 2 || neighbor > 3))
{
nextGen[row][col] = false;
}
else if ( (life[row][col] == false) && (neighbor == 3) )
{
nextGen[row][col] = true;
}
}neighbor = 0;
}
}
for (int row = 0; row < SIZE; row++)
{
for (int col = 0; col < SIZE; col++)
{
life[row][col] = nextGen[row][col];
}
}

}

0

Решение

Ваш код дважды учитывает количество соседей. Это потому, что, например, если row 0 и col 0, это делает row == 0 случай наверху, а также row == 0 дело внутри col == 0 если заявление примерно на 100 строк ниже.

Один из способов исправить это с помощью права else статьи. то есть сделать что-то вроде:

if (row == 0)
{
...
}
else if (row == 19)
{
...
}
else
{
...
}

Вы должны сделать это и для столбца.

Лучшее решение — рассмотреть все эти особые случаи и попытаться рационализировать их во что-то с менее повторяющимся кодом.

То, что вы пытаетесь достичь, — это предотвратить чтение за пределами границ массива.

Самый простой способ сделать это — иметь функцию для получения значения массива в row, col который проверяет row а также col и возвращается false если row или же col вне границ. Затем вы можете просто вызвать эту функцию для каждого из 8 окружающих блоков для каждой позиции, не имея особых случаев для строк 0 и 19 и столбцов 0 и 19.

Я предлагаю попробовать написать функцию, подобную приведенной выше, а не просто вставлять ее здесь для вас.

Редактировать: Также обратите внимание — вы не всегда устанавливаете значение в nextGenтаким образом, вы убиваете ячейки, которые имели жизнь с двумя или тремя соседями, вам может понадобиться переосмыслить выражение if / else при назначении в nextGen

1

Другие решения