Как красиво записать в массив координаты 8 соседних клеток?
У меня есть код:
void UpdateNeighborCells() {
NeighborCells [0] = {position.x--, position.y};
NeighborCells [1] = {position.x--, position.y--};
NeighborCells [2] = {position.x++ , position.y--};
NeighborCells [3] = {position.x-- , position.y++};
NeighborCells [4] = {position.x++ , position.y++};
NeighborCells [5] = {position.x, position.y--};
NeighborCells [6] = {position.x , position.y++};
NeighborCells [7] = {position.x++ , position.y};
}
У каждого человечка в моей игре есть позиция, и мне надо знать его соседние клетки и обновлять их каждый раз, когда он ходит; этот метод как раз это и делает. Выглядит не очень красиво, есть ли идеи, как можно сократить количество строк и сделать более "красивым"?
Ответы (2 шт):
Первое и важное, как подсказывает @StanislavVolodarskiy, вы перезаписываете значения переменных используя ++ и --. Врядли это то что вы хотите на самом деле сделать.
Самое простое для приближения к красоте и удобочитаемости это переменные покороче и выравнивание поровнее. Так вы хотя бы визуально будете видеть что всё в порядке (три раза +1, три раза -1 с каждой стороны и два раза просто):
void UpdateNeighborCells() {
p = position;
NeighborCells [0] = {p.x-1, p.y };
NeighborCells [1] = {p.x-1, p.y-1};
NeighborCells [2] = {p.x+1, p.y-1};
NeighborCells [3] = {p.x-1, p.y+1};
NeighborCells [4] = {p.x+1, p.y+1};
NeighborCells [5] = {p.x , p.y-1};
NeighborCells [6] = {p.x , p.y+1};
NeighborCells [7] = {p.x+1, p.y };
}
Также не повредит комментарий с уточнением порядка обхода, для наглядности:
// 152
// 0x7
// 364
Это кстати достаточно странный порядок, если алгоритм позволяет, то лучше поменять на что-то более очевидное, типа:
// 012
// 3x4
// 567
Я запустил ваш код и затем распечатал результат для исходной позиции (0, 0):
UpdateNeighborCells();
for (int i = 0; i < 8; ++i) {
std::cout << i << ": (" << NeighborCells[i].x << ", " <<
NeighborCells[i].y << ")\n";
}
Печать:
0: (0, 0) 1: (-1, 0) 2: (-2, -1) 3: (-1, -2) 4: (-2, -1) 5: (-1, 0) 6: (-1, -1) 7: (-1, 0)
Для наглядности я поместил индексы ячеек в таблицу, чтобы было видно каких соседей мы перебираем. Четыре ячейки пустые, в одной ячейке два индекса, в одной – три, диапазоны x и y смещены (должны быть [-1, 0, 1]):
| x = -2 | x = -1 | x = 0 | |
|---|---|---|---|
| y = -2 | 3 | ||
| y = -1 | 2, 4 | 6 | |
| y = 0 | 1, 5, 7 | 0 |
Я хочу сказать что это не работает. Речь не о красоте, а о правильности.
Заменим инкременты на обычные выражения без побочных эффектов:
void UpdateNeighborCells() {
NeighborCells[0] = {position.x - 1, position.y };
NeighborCells[1] = {position.x - 1, position.y - 1};
NeighborCells[2] = {position.x + 1, position.y - 1};
NeighborCells[3] = {position.x - 1, position.y + 1};
NeighborCells[4] = {position.x + 1, position.y + 1};
NeighborCells[5] = {position.x , position.y - 1};
NeighborCells[6] = {position.x , position.y + 1};
NeighborCells[7] = {position.x + 1, position.y };
}
Печать:
0: (-1, 0) 1: (-1, -1) 2: (1, -1) 3: (-1, 1) 4: (1, 1) 5: (0, -1) 6: (0, 1) 7: (1, 0)
Размещение изменилось, даже диапазон. И теперь все восемь соседей упомянуты в списке:
| x = -1 | x = 0 | x = 1 | |
|---|---|---|---|
| y = -1 | 1 | 5 | 2 |
| y = 0 | 0 | 7 | |
| y = 1 | 3 | 6 | 4 |
Уменьшить количество кода можно так:
void UpdateNeighborCells() {
const int x = position.x;
const int y = position.y;
NeighborCells[0] = {x - 1, y };
NeighborCells[1] = {x - 1, y - 1};
NeighborCells[2] = {x + 1, y - 1};
NeighborCells[3] = {x - 1, y + 1};
NeighborCells[4] = {x + 1, y + 1};
NeighborCells[5] = {x , y - 1};
NeighborCells[6] = {x , y + 1};
NeighborCells[7] = {x + 1, y };
}
Если хочется решение с инкрементами, то вот оно. Порядок обхода – слева по часовой стрелке:
void UpdateNeighborCells() {
int x = position.x;
int y = position.y;
NeighborCells[0] = {--x, y}; // шаг из центра налево
NeighborCells[1] = { x, --y}; // шаг вверх
NeighborCells[2] = {++x, y}; // два шага вправо
NeighborCells[3] = {++x, y};
NeighborCells[4] = { x, ++y}; // два шага вниз
NeighborCells[5] = { x, ++y};
NeighborCells[6] = {--x, y}; // два шага налево
NeighborCells[7] = {--x, y};
}