Обертывание сетки по модулю

Я пытаюсь написать программу, которая реализует игру жизни Конвея на сетке размером 20х60 клеток. Сетка должна обернуться так, чтобы левая сторона была соединена с правой стороной, а верхняя часть — с нижней.

Таким образом, любая клетка с положением (0, col), будет сосед в (maxRow, col), Любая ячейка с позицией (row, 0) будет сосед в (row, maxCol),

Следующая функция должна подсчитывать количество соседних ячеек. Это работает для координат не по краям, но не для тех, которые есть. Например, если есть точки на (0, 10), (0, 11), (0, 12), а также (0, 10) передается в функцию, она будет возвращать большое число как число соседей вместо 1, Я знаю, что мод оператора % было бы полезно, но я не понимаю, как его использовать.

{
int i, j;
int count = 0;
for (i = row - 1; i <= row + 1; i++)
for (j = col - 1; j <= col + 1; j++)
count += grid[i][j]; }

if (row==maxrow-1 || row==0)
count = count+ grid [(row-(maxrow-1))*-1][col-1]+grid[(row-(maxrow-1))*-1][col]+grid[(row-(maxrow-1))*-1][col+1];

if (col==0 || col==maxcol-1)
count=count +grid[row-1][(col-(maxcol-1))*-1]+grid[row][(col-(maxcol-1))*-1]+grid[row+1][(col-(maxcol-1))*-1];count -= grid[row][col];
return count;
}

1

Решение

Прежде чем предлагать решение, позвольте мне сделать несколько замечаний.

  • Добавление некоторых значений сетки и последующее вычитание других значений сетки не очень хорошая идея. Вы должны рассчитать правильные координаты сетки для начала.

  • Когда ты пишешь count += grid[i][j];, вы используете индексы массива, которые могут быть недействительными. Например, i = row - 1 когда row ноль дает i ценность -1,

  • Ваш код подразумевает, что maxrow это количество строк, потому что вы пишете maxrow-1, но имя maxrow предлагает максимальный индекс строки. Это смущает. Было бы лучше назвать количество строк numRows, а затем самый большой индекс строки numRows - 1, Точно так же было бы лучше заменить maxcol с numCols,

Теперь к сути дела. Значение row - 1 может быть равен -1, а также row + 1 может быть равен numRows, Оба они являются недопустимыми индексами строк. Так же, col - 1 а также col + 1 может привести к неверным индексам столбцов -1 а также numCols, Один из способов решения этой проблемы — проверить эти конкретные значения и заменить их индексами с циклическим переходом:

int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
int R = i;
if (R == -1) {
R = numRows - 1;
} else if (R == numRows) {
R = 0;
}
for (int j = col - 1; j <= col + 1; j++) {
if (i == row && j == col) {
continue;  // Skip grid[row][col].
}
int C = j;
if (C == -1) {
C = numCols - 1;
} else if (C == numCols) {
C = 0;
}
count += grid[R][C];
}
}

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

Мы хотели бы написать i % numRowsкроме C ++ оценивает это как -1, когда i это -1. Это потому, что операция по модулю неоднозначна для отрицательных значений и C ++ выбрал интерпретацию это не гарантирует неотрицательные результаты.

Чтобы исправить эту проблему, мы добавляем numRows в i перед взятием по модулю numRows, Это гарантирует, что мы всегда берем модуль положительного числа. Теперь мы можем посчитать количество живых клеток среди восьми соседей grid[row][col] следующее.

int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if (i == row && j == col) {
continue;  // Skip grid[row][col].
}
count += grid[(i + numRows) % numRows][(j + numCols) % numCols];
}
}
1

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