简体   繁体   中英

c++ - sorting std::vector in pathfinding

I'm trying to implement a rough pathfinding example into a game i'm working on. I'm at a point where I need to sort a std::vector<Tile*> and i've tried to do so with the following but I get a bunch of errors I can't figure out. I've also tried to change the references in the sortF struct to pointers, but I get another error - Comparison between pointer and integer ('Tile *' and 'int') .

The error in question is: No matching function for call to object of type 'Stage::sortF'

Wondering what exactly i'm doing wrong here.

(and if anyone had any comments on the pathfinding that would be good too)

in Stage.h public

struct sortF
{
    bool operator()(const Tile& a, const Tile& b) const
    {
        return a.f > b.f;
    }
};

in Stage.cpp

bool Stage::tilePath(Tile* start, Tile* end)
{
    std::vector<Tile*> path;
    std::vector<Tile*> open;
    std::vector<Tile*> closed;
    start->previousTile = start;
    start->g = 0;
    start->h = 0;
    start->f = 0;

    int i, j;
    float g, h, f;

    int sx, sy, ex, ey;

    int cost;

    Tile* current = start;
    Tile* neighbor = NULL;
    Tile* previous = NULL;
    std::cout << neighbor << std::endl;

    while(current != end) {
        sx = fmaxf(0, current->x - 1);
        sy = fmaxf(0, current->y - 1);
        ex = fminf(17 - 1, current->x + 1);
        ey = fminf(6 - 1, current->y + 1);

        for(i = sx; i <= ex; i++) {
            for(j = sy; j <= ey; j++) {
                neighbor = tiles[((j - 1) * 17) + i - 1];
                if(neighbor == current || !neighbor->walkable) continue;
                previous = current;
                if(false /* raytrace */) {

                } else {
                    cost = (current->x != neighbor->x || current->y != neighbor->y) ? 1.4 : 1;
                    g = current->g + cost;
                    h = euclidian(neighbor, end);
                    f = g + h;
                }

                if(std::find(open.begin(), open.end(), neighbor) != open.end() ||
                   std::find(closed.begin(), closed.end(), neighbor) != closed.end()) {
                    if(neighbor->f > f) {
                        neighbor->f = f;
                        neighbor->g = g;
                        neighbor->h = h;
                        neighbor->previousTile = current;
                    }
                } else {
                    neighbor->f = f;
                    neighbor->g = g;
                    neighbor->h = h;
                    neighbor->previousTile = current;
                    open.push_back(current);
                }
            }
        }

        closed.push_back(current);
        if(open.size() == 0) {
            return false;
        }
        std::sort(open.begin(), open.end(), sortF());
        current = open[0];
        std::remove(open.begin(), open.end(), 0);
    }
    return true;
}

Note: You didn't include your error messages, so the following answer is more or less based on view compiling:

sortF() , not sortF

error: expected primary-expression before ‘)’ token
    std::sort(open.begin(), open.end(), sortF);
                                             ^

You need an instance of sortF , not the type struct sortF . Either use sortF() to create a temporary object, or use a function instead of a functor:

bool sortF(const Tile& a, const Tile& b)
{
    return a.f > b.f;
}

Tile* vs const Tile&

You use std::sort on a std::vector<Tile*> , but your comparing function uses const Tile& as parameter. Either use std::vector<Tile> or correct the type in your function:

bool sortF(const Tile* a, const Tile* b)
{
    return a->f > b->f;
}

Since the elements of the std::vector of type Tile* , the function that compares two items of the std::vector must take two Tile* s.

struct sortF
{
    bool operator()(Tile* ap, Tile* bp) const
    {
        return a->f > b->f;
    }
};

You definitely must change references to pointers in the comparer function. You didn't tell where exactly you got the error about comparison between pointer and integer, but I believe it happened on this line:

std::remove(open.begin(), open.end(), 0);

std::remove() takes a value type of the container, not an index. What you wanted to do is probably

open.pop_front()

That said, this operation as well as sorting take quite a bit of time, and as Javi V commented, using heap structure is preferable here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM