0

I am writing a program that uses a hexagon map (obviously in the output seen below it appears as a square, but the numbers will make sense for a hexagon shape) to generate a path from a certain point. 0 indicates the goal, -2 indicates an off limits section, and any other number indicates a distance from that spot to the goal (0). I've written 6 functions to populate surrounding neighbors. These functions feed into another function that populates the map.. or is supposed to. I find with certain inputs, the map population goes awry on the left portion. I've done a desk check and can't figure out why. Any fresh eyes would help greatly, I've been looking at this for some time:

       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);
            }

        }
    }

some example input: goal is at (12, 12), off limits cell: (1, 19). And I get this mess:

 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 

1 Answers1

0

It looks like the way you're calculating directions is off. You would probably do well to name them, instead of getNeighborsx, to getNorthNeighbor, getSouthNeighbor, getNortheastNeighbor, getSouthwestNeighbor, getNorthwestNeighbor, getSoutheastNeighbor, as that would make it easy to identify which functions are doing what and why they might not be behaving as expected.

When I made a hexagonal grid, I defined directions like this:

enum direction {
    north, south, northeast, southwest, northwest, southeast
};

And I got relative points from a direction like this:

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);
    }
}

Your getNeighbors5 and getNeighbors6 functions are what I believe are at fault, because they change direction based on suspect criteria:

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;
        }

    }
}

It doesn't make sense that you're changing which direction this is based on which column it's in. SouthEast of a cell (if it's defined as a composite of South and NorthEast) is always going to be -1, +1 of that cell.

I've attached an image of a hexagonal grid, I suggest you use it to work out the positions of these cells. Depending on how you've defined North/NorthEast, you may need to rotate the directions of the Axis' I provided, but it should illuminate where you might have gone wrong.

image of hexagonal grid

Xirema
  • 19,889
  • 4
  • 32
  • 68
  • Would I really have to replace all my getNeighbor functions completely? I understand how the naming can be off but if I alter the directions (not based on column), do I have to use a switch statement – rabbitinred Dec 02 '15 at 14:48
  • Only 5 and 6 would need to be replaced, as far as I'm concerned, since in the coordinate system I'm proposing, directions 1-4 still work, they just have to be assigned meaning. I used a switch statement for the purpose of making the code concise, but you're free to keep them as distinct functions. I just can't recommend using Offset Notation for addressing the cells, as it is incredibly difficult to debug. – Xirema Dec 02 '15 at 15:00