Я пытаюсь создать программу, способную создавать все виды клеточных автоматов, такие как игра жизни Конвея и все остальное тоже.
Графическая реализация уже работает отлично, поэтому я бы не стал тратить на это ваше время (особенно из-за того, что он использует библиотеки Allegro), но функции, которые подсчитывают ячейки, не работают должным образом.
Это то, что у меня есть на данный момент. (код в порядке, я просто разрываю его с комментариями, чтобы все было понятно для вас)
Предварительные определения:
#define fldwidth 110
#define fldheight 140
Структура для графики:
typedef struct tiles
{
unsigned char red, green, blue;
}tiles;
Две предопределенные структуры: код RGB живой и мертвой тестовой ячейки.
const tiles TEST_ALIVE = {200,0,0};
const tiles TEST_DEAD = {100,0,0};
Функция, которая проверяет цветовое равенство структурной переменной и постоянной структуры.
bool equality(tiles& a, const tiles& b)
{
if (a.red == b.red && a.green == b.green && a.blue == b.blue)
{
return true;
} else {
return false;
}
}
Основная функция. Он получает два массива структур (первый — текущий раунд, второй — место подсчета; в цикле, после подсчета, массив b будет скопирован в массив); при запуске он выполняет следующие шаги для каждой структуры: подсчитывает, сколько живых клеток он имеет в своем соседстве (если это живая клетка, он начинает с -1, чтобы не считать себя соседями, в противном случае он регулярно начинается с 0), тогда, если само по себе НЕ является живой тестовой ячейкой (но что-либо еще) и имеет 5 соседей, она становится живой тестовой ячейкой; если сама является живой тестовой ячейкой и имеет 2 соседей, она становится мертвой.
void Test(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(arra[i][j], TEST_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<j+1;b++)
{
for (a=i-1;a<i+1;a++)
{
if (equality(arra[a][b], TEST_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
{
arrb[i][j] = TEST_ALIVE;
}
if (equality(arra[i][j], TEST_ALIVE) == true && counter == 2)
{
arrb[i][j] = TEST_DEAD;
}
}
}
}
Проблема в том, что, когда начинается подсчет, каждая живая клетка сразу же становится мертвой в первом раунде, а иногда они просто исчезают, даже не становясь мертвой клеткой (которая, очевидно, более темного красного цвета), и это происходит почти для каждого «счетчика == XY «проверить.
У меня уже есть несколько советов, но я понятия не имею, почему это не работает. Есть ли у него логический сбой? Потому что я не вижу ошибки, хотя она и есть.
РЕДАКТИРОВАТЬ:
arra[fldwidth][fldheight]
заменяется
arra[i][j]
а также
arrb[i][j] = arra[i][j];
добавлен. Теперь все остается как было положено.
Почему вы получаете доступ arra[fldwidth][fldheight]
для проверки на равенство? Это за пределами массива, один элемент за последним элементом в массиве! То, что вы хотите получить доступ arra[i][j]
,
И если arrb
начинается как копия arra
, вы, вероятно, хотите добавить arrb[i][j] = arra[i][j];
перед двумя проверками равенства. Таким образом, если ячейка не соответствует ни одному из двух правил изменения состояния, она сохранит свое текущее состояние.
Редактировать:
Вы также должны позволить циклу работать между i-1 и i + 1, поэтому оно должно быть: for (a = i-1; a <= i+1; a++)
, то же самое для б!
Я думаю, что ваша ошибка в строке:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == false && counter == 5)
Это должно быть:
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
и аналогично для строки:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == true && counter == 2)