Я пишу программу, которая использует карту шестиугольника (очевидно, в выводе, показанном ниже, он выглядит как квадрат, но числа будут иметь смысл для формы шестиугольника), чтобы сгенерировать путь из определенной точки. 0 указывает на цель, -2 указывает на запретный участок, а любое другое число указывает расстояние от этой точки до цели (0). Я написал 6 функций для заселения окружающих соседей. Эти функции передаются в другую функцию, которая заполняет карту .. или должна. Я обнаружил, что при определенных входных данных население карты в левой части искажается. Я проверил на столе и не могу понять почему. Любые свежие глаза очень помогли бы, я смотрю на это в течение некоторого времени:
struct Point {
int r;
int c;
};
Queue <Point> q;
Point getNeighbors1(int r, int c) {
int n1r, n1c;
if (r < (ROW-1) ) {
n1r = r+1;
n1c = c;
Point neighborLoc1;
neighborLoc1.r = n1r;
neighborLoc1.c = n1c;
return neighborLoc1;
}
}
Point getNeighbors2(int r, int c) {
int n2r, n2c;
if (r > 0) {
n2r = r-1;
n2c = c;
Point neighborLoc2;
neighborLoc2.r = n2r;
neighborLoc2.c = n2c;
return neighborLoc2;
}
}
Point g
etNeighbors3(int r, int c) {
int n3r, n3c;
if (c < (COL-1) ) {
n3r = r;
n3c = c+1;
Point neighborLoc3;
neighborLoc3.r = n3r;
neighborLoc3.c = n3c;
return neighborLoc3;
}
}
Point getNeighbors4(int r, int c) {
int n4r, n4c;if (c > 0) {
n4r = r;
n4c = c-1;
Point neighborLoc4;
neighborLoc4.r = n4r;
neighborLoc4.c = n4c;
return neighborLoc4;
}
}
Point getNeighbors5(int r, int c) {
int n5r, n5c;
if (c % 2 == 0) {
if (r > 0 && c < COL-1 ) {
n5r = r-1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
else {
if (r < (ROW-1) && c < (COL-1) ) {
n5r = r+1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
}
Point getNeighbors6(int r, int c) {
int n6r, n6c;
if (c % 2 == 0) {
if (r > 0 && c > 0) {
n6r = r-1;
n6c = c-1;
Point neighborLoc6;
neighborLoc6.r = n6r;
neighborLoc6.c = n6c;
return neighborLoc6;
}
}
else {
if (r < (ROW-1) && c > 0) {
n6r = r+1;
n6c = c-1;
Point neighborLoc6;
neighborLoc6.r = n6r;
neighborLoc6.c = n6c;
return neighborLoc6;
}
}
}
//populate grid
void numberScheme (Queue<Point> pQ, int map[ROW][COL]) {
while (!pQ.isEmpty()) {
Point p = pQ.dequeue();
Point n1 = getNeighbors1(p.r, p.c);
if (map[n1.r][n1.c] == -1) {
map[n1.r][n1.c] = map[p.r][p.c] + 1;
pQ.enqueue(n1);
}
Point n2 = getNeighbors2(p.r, p.c);
if (map[n2.r][n2.c] == -1) {
map[n2.r][n2.c] = map[p.r][p.c] + 1;
pQ.enqueue(n2);
}
Point n3 = getNeighbors3(p.r, p.c);
if (map[n3.r][n3.c] == -1) {
map[n3.r][n3.c] = map[p.r][p.c] + 1;
pQ.enqueue(n3);
}
Point n4 = getNeighbors4(p.r, p.c);
if (map[n4.r][n4.c] == -1) {
map[n4.r][n4.c] = map[p.r][p.c] + 1;
pQ.enqueue(n4);
}
Point n5 = getNeighbors5(p.r, p.c);
if (map[n5.r][n5.c] == -1) {
map[n5.r][n5.c] = map[p.r][p.c] + 1;
pQ.enqueue(n5);
}
Point n6 = getNeighbors6(p.r, p.c);
if (map[n6.r][n6.c] == -1) {
map[n6.r][n6.c] = map[p.r][p.c] + 1;
pQ.enqueue(n6);
}
}
}
Пример ввода: цель в (12, 12), ячейка вне пределов: (1, 19). И я получаю этот беспорядок:
9 9 10 11 12 13 14 14 14 13 13 12 12 12 13 13 14 14 15 15
8 9 10 11 12 13 14 13 13 12 12 11 11 11 12 12 13 13 14 -2
9 10 10 11 12 13 13 12 12 11 11 10 10 10 11 11 12 12 13 13
10 11 11 12 12 12 12 11 11 10 10 9 9 9 10 10 11 11 12 12
11 12 12 12 12 11 11 10 10 9 9 8 8 8 9 9 10 10 11 11
11 11 12 11 11 10 10 9 9 8 8 7 7 7 8 8 9 9 10 10
10 10 11 10 10 9 9 8 8 7 7 6 6 6 7 7 8 8 9 9
9 9 10 9 9 8 8 7 7 6 6 5 5 5 6 6 7 7 8 8
8 9 10 9 8 7 7 6 6 5 5 4 4 4 5 5 6 6 7 7
8 9 10 9 8 7 6 5 5 4 4 3 3 3 4 4 5 5 6 7
8 9 10 9 8 7 6 5 4 3 3 2 2 2 3 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 1 1 1 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 2 1 2 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 4 3 3 2 3 3 4 4 5 6 7
8 9 10 9 8 7 6 6 5 5 4 4 3 4 4 5 5 6 6 7
9 10 10 9 8 8 7 7 6 6 5 5 4 5 5 6 6 7 7 8
10 10 10 10 9 9 8 8 7 7 6 6 5 6 6 7 7 8 8 9
9 9 10 11 10 10 9 9 8 8 7 7 6 7 7 8 8 9 9 10
8 9 10 11 11 11 10 10 9 9 8 8 7 8 8 9 9 10 10 11
Похоже, что вы рассчитываете направление отключено. Вам, вероятно, лучше назвать их, а не getNeighborsx
, чтобы getNorthNeighbor
, getSouthNeighbor
, getNortheastNeighbor
, getSouthwestNeighbor
, getNorthwestNeighbor
, getSoutheastNeighbor
, поскольку это позволит легко определить, какие функции выполняют, что и почему они могут вести себя не так, как ожидалось.
Когда я сделал гексагональную сетку, я определил направления следующим образом:
enum direction {
north, south, northeast, southwest, northwest, southeast
};
И я получил относительные баллы с такого направления:
point point::getRelativePoint(const direction & d) const {
switch (d) {
case north: return point(x + 1, y); //North and south are defined along the X axis, for our purposes
case south: return point(x - 1, y);
case northeast: return point(x, y + 1); //Northeast and Southwest are defined along the Y axis
case southwest: return point(x, y - 1);
case southeast: return point(x - 1, y + 1); //Northwest and Southeast can be defined by adding together other directions: Northwest is North + Southwest, and Southeast is South + Northeast.
case northwest: return point(x + 1, y - 1);
}
}
Ваш getNeighbors5
а также getNeighbors6
Я считаю, что виноваты функции, потому что они меняют направление на основе подозрительных критериев:
Point getNeighbors5(int r, int c) {
int n5r, n5c;
if (c % 2 == 0) {
if (r > 0 && c < COL-1 ) {
n5r = r-1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
else {
if (r < (ROW-1) && c < (COL-1) ) {
n5r = r+1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
}
Не имеет смысла менять направление в зависимости от того, в каком столбце он находится. Юго-восток ячейки (если он определен как составная часть юга и северо-востока) всегда будет равен -1, +1 от этого клетка.
Я прикрепил изображение гексагональной сетки, я предлагаю вам использовать его для определения положения этих ячеек. В зависимости от того, как вы определили North / NorthEast, вам может потребоваться повернуть направления Оси, которые я указал, но она должна подсвечивать, где вы могли ошибиться.
Других решений пока нет …