worked on grid walker
This commit is contained in:
@@ -84,43 +84,67 @@ namespace GW3 {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* data-structure to track to-be-visited nodes
|
||||
* push_back, pop_front
|
||||
* as pop_front is costly, we omit the pop and use a head-index instead
|
||||
* memory-consumption vs speed
|
||||
*/
|
||||
struct ToVisit {
|
||||
size_t nextIdx = 0;
|
||||
std::vector<uint32_t> vec;
|
||||
ToVisit() {vec.reserve(256);}
|
||||
void add(const uint32_t nodeIdx) {vec.push_back(nodeIdx);}
|
||||
uint32_t next() {return vec[nextIdx++];}
|
||||
bool empty() const {return nextIdx >= vec.size();}
|
||||
};
|
||||
|
||||
/** get an iterator over all nodes reachable from the given start */
|
||||
template <typename Node> class ReachableIteratorUnsorted {
|
||||
template <typename Node, typename Conditions> class ReachableIteratorUnsorted {
|
||||
|
||||
const Grid<Node>& grid;
|
||||
const Node& start;
|
||||
|
||||
Node* curNode = nullptr;
|
||||
std::unordered_set<uint32_t> visited;
|
||||
std::vector<uint32_t> toVisit;
|
||||
ToVisit toVisit;
|
||||
|
||||
Conditions cond;
|
||||
|
||||
public:
|
||||
|
||||
ReachableIteratorUnsorted(const Grid<Node>& grid, const Node& start) : grid(grid), start(start) {
|
||||
toVisit.push_back(start.getIdx());
|
||||
ReachableIteratorUnsorted(const Grid<Node>& grid, const Node& start, const Conditions cond) : grid(grid), start(start), cond(cond) {
|
||||
toVisit.add(start.getIdx());
|
||||
}
|
||||
|
||||
bool hasNext() const {
|
||||
return !toVisit.empty();
|
||||
}
|
||||
|
||||
const Node& next(const std::function<bool(const Node&)>& skip) {
|
||||
|
||||
const uint32_t curIdx = toVisit.front(); //visit from inside out (needed for correct distance)
|
||||
toVisit.erase(toVisit.begin());
|
||||
visited.insert(curIdx);
|
||||
//const Node& next(const std::function<bool(const Node&)>& skip) {
|
||||
//template <typename Skip> const Node& next(const Skip skip) {
|
||||
const Node& next() {
|
||||
|
||||
// get the next to-be-visited node
|
||||
const uint32_t curIdx = toVisit.next(); //visit from inside out (needed for correct distance)
|
||||
const Node& curNode = grid[curIdx];
|
||||
|
||||
for (int i = 0; i < curNode.getNumNeighbors(); ++i) {
|
||||
// mark as "visited"
|
||||
visited.insert(curIdx);
|
||||
|
||||
const int neighborIdx = curNode.getNeighborIdx(i);
|
||||
// get all neighbors
|
||||
const int numNeighbors = curNode.getNumNeighbors();
|
||||
for (int i = 0; i < numNeighbors; ++i) {
|
||||
|
||||
const uint32_t neighborIdx = curNode.getNeighborIdx(i);
|
||||
const Node& neighbor = grid[neighborIdx];
|
||||
|
||||
const bool visit = cond.visit(neighbor) ;
|
||||
|
||||
// not yet reached -> store distance
|
||||
if (!skip(neighbor)) {
|
||||
if (visit) {
|
||||
if (visited.find(neighborIdx) == visited.end()) {
|
||||
toVisit.push_back(neighborIdx);
|
||||
toVisit.add(neighborIdx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user