Оборачиваем вокруг сетки по модулю
Я пытаюсь написать программу, которая реализует игру жизни Конвея на сетке 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];
}
}