Определение действительных соседних ячеек квадрата, хранящегося в виде массива - PullRequest
1 голос
/ 13 января 2010

У меня есть массив (скажем, из 9 элементов), который я должен рассматривать как квадрат (3 на 3). Для упрощения вопроса это массив на основе одного (т. Е. Индексирование начинается с 1 вместо 0).

Моя цель - определить действительные соседние квадраты относительно начальной точки.

Другими словами, как он хранится в памяти: 1 2 3 4 5 6 7 8 9

Как я к этому отношусь:
7 8 9
4 5 6
1 2 3

Я уже знаю, как двигаться вверх и вниз и проверять выход за пределы (1> = current_index <= 9) </p>

edit: я знаю, что приведенный выше тест является слишком общим, но он прост и работает.

//row_size = 3, row_step is -1, 0 or 1 depending on if we're going left,
//staying put or going right respectively.
current_index += (row_size * row_step); 

Как проверить состояние вне пределов при движении влево или вправо? Концептуально я знаю, что это включает определение того, находится ли 3 (например) в той же строке, что и 4 (или если 10 находится даже в том же квадрате, что и 9, в качестве альтернативного примера, учитывая, что несколько квадратов находятся в одном массиве вплотную) , но я не могу понять, как это определить. Я полагаю, там где-то по модулю, но где?

Большое спасибо,
Джефф

Добавление:
Вот результирующий код, измененный для использования с массивом, начинающимся с нуля (я очистил код смещения, присутствующий в проекте), который обходит соседние квадраты.

bool IsSameSquare(int index0, int index1, int square_size) {
  //Assert for square_size != 0 here
  return (!((index0 < 0) || (index1 < 0))
      && ((index0 < square_size) && (index1 < square_size)))
      && (index0 / square_size == index1 / square_size);
}
bool IsSameRow(int index0, int index1, int row_size) {
  //Assert for row_size != 0 here
  return IsSameSquare(index0, index1, row_size * row_size)
  && (index0 / row_size == index1 / row_size);
}
bool IsSameColumn(int index0, int index1, int row_size) {
  //Assert for row_size != 0 here
  return IsSameSquare(index0, index1, row_size * row_size)
      && (index0 % row_size == index1 % row_size);
}

//for all possible adjacent positions
for (int row_step = -1; row_step < 2; ++row_step) {
  //move up, down or stay put.
  int row_adjusted_position = original_position + (row_size * row_step);
  if (!IsSameSquare(original_position, row_adjusted_position, square_size)) {
    continue;
  }
  for (int column_step = -1; column_step < 2; ++column_step) {
    if ((row_step == 0) & (column_step == 0)) { continue; }
    //hold on to the position that has had its' row position adjusted.
    int new_position = row_adjusted_position;

    if (column_step != 0) {
      //move left or right
      int column_adjusted_position = new_position + column_step;
      //if we've gone out of bounds again for the column.
      if (IsSameRow(column_adjusted_position, new_position, row_size)) {
        new_position = column_adjusted_position;
      } else {
        continue;                          
      }
    } //if (column_step != 0)
    //if we get here we know it's safe, do something with new_position
    //...
  } //for each column_step
} //for each row_step

Ответы [ 3 ]

3 голосов
/ 13 января 2010

Это проще, если вы использовали индексацию на основе 0. Эти правила работают, если вы вычли 1 из всех своих индексов:

  • Два индекса находятся в одном квадрате, если (a / 9) == (b / 9) и a> = 0 и b> = 0.
  • Два индекса находятся в одной строке, если они находятся в одном квадрате и (a / 3) == (b / 3).
  • Два индекса находятся в одном столбце, если они находятся в одном квадрате и (a% 3) == (b% 3).
0 голосов
/ 13 января 2010

Есть несколько способов сделать это, я выбираю странный для развлечения. Используйте модуль.

Если ваши строки имеют размер 3, просто используйте модуль 3 и два простых правила.

If currPos mod 3 = 0 and (currPos+move) mod 3 = 1 then invalid
If currPos mod 3 = 1 and (currPos+move) mod 3 = 0 then invalid

эта проверка для вас, прыгнув на два новых ряда, вы также можете сделать одно правило, как это

if (currPos mod 3)-((currPos+move) mod 3)> 1 then invalid

Приветствия

0 голосов
/ 13 января 2010

Для этого вы должны использовать многомерный массив.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...