0

I am working with a few friends on a Dungeon-game and am working on pathfinding. The game is tile-based and the pathfinding we are planning to implement is this:

class PathMapper generates a grid of the distance every tile is from a given tile

class Monster uses this grid to travel toward a given tile (right now, always a player)

We are planning on having 4 players, but we/I would like to have the script support a dynamic number. Each player has an ID in the form of an integer.

One grid generated by PathMapper is required for each player, and all monsters can share them (as slow as generating the grid is, only doing it once per player, for all monsters, seems like a decent solution to pathfinding).

I have a class called "PathMapper" which generates grids of the distances tiles are from a starting, tile. In theory, 4 of these would be created -- one for each player. For an enemy to path find to a player, it would ask for the player's ID, and then ask for the corresponding grid of tiles, which it would use to pathfind. The server updates these grids with "createMap(playerID, playerXPosition, playerYPosition)".

So each grid is a vector-of-vectors that is mapped to the player's ID in the private map "pathMap", the values of which monsters would access with "getLocalPath()"

The problem is that, though "createMap" compiles fine, once the first wall is attempted to be copied ("pathMap[ID][x].push_back(9000);") I get "EXE_BAD_ACCESS". I should note that it gets through about a dozen iterations before trying (and failing) to insert "9000" I am sure dungeon->width and dungeon->height are correct (both are 20 right now; will probably be ~100 for the real game), and the 'correctness' of the ID shouldn't affect the accessor of the code, right?

I'm a bit baffled, b/c what I think I'm doing is reserving space, looping through it, and trying to access the memory I JUST reserved:

reserve(20)
for(i=0; i<20; i++)
    reserve(20)
    for(j=0; j<20; j++)
        access(i,j) // error!?

Here is the code:

class PathMapper{
public:
    PathMapper(Dungeon* d);
    void createMap(int ID, int x, int y);

    // returns values of the surrounding tiles (up, right, down, left)
    std::vector<int> getLocalPath(int ID, int x, int y);
private:
    Dungeon* dungeon;
    std::vector< std::vector<bool> > wallBitmap;
    std::map<int, std::vector< std::vector<int> > > pathMap;
}

PathMapper::PathMapper(Dungeon* d) {
    dungeon = d;
    wallBitmap = dungeon->getWalls(); // bools tell if there is a wall on a tile
}

void PathMapper::createMap(int ID, int x, int y) {
    pathMap[ID].reserve(dungeon->width());
    for(int x=0; x<dungeon->width(); x++) {
        pathMap[ID][x] = std::vector<int>();
        pathMap[ID][x].reserve(dungeon->height());
        for(int y=0; y<dungeon->height(); y++) {
            if(wallBitmap[x][y]) {
                pathMap[ID][x].push_back(9000); // error is here
            }
            else {
                pathMap[ID][x][y] = -1;
            }
        }
    }

    // code to calculate values here; shouldn't affect the code above

}
kryger
  • 12,906
  • 8
  • 44
  • 65
evangambit
  • 31
  • 6
  • This is a bit verbose. Can you focus on the error and the code causing the error? – jww Apr 08 '14 at 00:19

2 Answers2

3

reserve does not change the size of the vector (only capacity), you need resize.

Spock77
  • 3,256
  • 2
  • 30
  • 39
1

Either

use resize :

pathMap[ID].resize(dungeon->width());
...
pathMap[ID][x] = std::vector<int>();
pathMap[ID][x].resize(dungeon->height());

or pass the size directly in the constructor:

pathMap[ID].resize(dungeon->width());
...
pathMap[ID][x] = std::vector<int>(dungeon->height());