void readIndexSetFromFile(IndexSet<Index2D> &Lambda, string filename) { std::ifstream infile (filename.c_str()); if (infile.is_open()) { cerr << " Indexset file is open." << endl; } else { cerr << " Indexset file " << filename.c_str() << " is not open." << endl; } int t1,t2; int j1,j2; long k1,k2; T coeff; while(!infile.eof()) { infile >> t1 >> j1 >> k1 >> t2 >> j2 >> k2 >> coeff; if (t1 == 1 && t2 == 1) { Index1D index_x(j1,k1,XWavelet); Index1D index_y(j2,k2,XWavelet); Lambda.insert(Index2D(index_x,index_y)); } else if (t1 == 1 && t2 == 0) { Index1D index_x(j1,k1,XWavelet); Index1D index_y(j2,k2,XBSpline); Lambda.insert(Index2D(index_x,index_y)); } else if (t1 == 0 && t2 == 1) { Index1D index_x(j1,k1,XBSpline); Index1D index_y(j2,k2,XWavelet); Lambda.insert(Index2D(index_x,index_y)); } else if (t1 == 0 && t2 == 0) { Index1D index_x(j1,k1,XBSpline); Index1D index_y(j2,k2,XBSpline); Lambda.insert(Index2D(index_x,index_y)); } else { std::cerr << "Could not read file." << std::endl; exit(1); return; } } }
Passage::Passage(GameModule &module, const int x0, const int y0, const int x1, const int y1, const uint8_t mask) : _module(module), _area(Vector2f(x0 * Info<float>::Grid::Size(), y0 * Info<float>::Grid::Size()), Vector2f((x1+1) * Info<float>::Grid::Size(), (y1+1) * Info<float>::Grid::Size())), _music(NO_MUSIC), _mask(mask), _open(true), _isShop(false), _shopOwner(SHOP_NOOWNER), _passageFans() { //Build the list of all tiles contained within this passage for (int y = y0; y <= y1; ++y) { for (int x = x0; x <= x1; ++x) { _passageFans.push_back(module.getMeshPointer()->getTileIndex(Index2D(x, y))); } } }
bool AStar::find_path(const std::shared_ptr<const ego_mesh_t>& mesh, uint32_t stoppedby, const int src_ix, const int src_iy, int dst_ix, int dst_iy) { /// @author ZF /// @details Explores up to MAX_ASTAR_NODES number of nodes to find a path between the source coordinates and destination coordinates. // The result is stored in a node list and can be accessed through AStar_get_path(). Returns false if no path was found. float weight; // do not start if the initial point is off the mesh if (Index1D::Invalid == mesh->getTileIndex(Index2D(src_ix, src_iy))) { #ifdef DEBUG_ASTAR printf("AStar failed because source position is off the mesh.\n"); #endif return false; } struct Offset { Offset(int setX, int setY) : x(setX), y(setY) {} int x; int y; }; //Explore all nearby nodes, including diagonal ones static const std::array<Offset, 8> EXPLORE_NODES = { Offset(-1, -1), Offset(-1, 0), Offset(-1, 1), Offset(0, -1), Offset(1, -1), Offset(1, 1), Offset(1, 0), Offset(0, 1) }; //Node sorting algorithm (lowest weight first) auto comparator = [](const std::shared_ptr<Node> &first, const std::shared_ptr<Node> &second){ return first->weight < second->weight; }; //Set of closed nodes std::unordered_set<int> closedNodes; std::priority_queue<std::shared_ptr<Node>, std::vector<std::shared_ptr<Node>>, decltype(comparator)> openNodes(comparator); //be a bit flexible if the destination is inside a wall if (mesh->tile_has_bits(Index2D(dst_ix, dst_iy), stoppedby)) { bool foundOpenSpace = false; //check all tiles edging to this one, including corners for(const auto& offset: EXPLORE_NODES) { //Did we find a free tile? if (!mesh->tile_has_bits(Index2D(dst_ix + offset.x, dst_iy + offset.y), stoppedby)) { dst_ix = dst_ix + offset.x; dst_iy = dst_iy + offset.y; foundOpenSpace = true; break; } } if(!foundOpenSpace) { #ifdef DEBUG_ASTAR printf("AStar failed because goal position is impassable (and no nearby non-impassable tile found).\n"); #endif return false; } } // restart the algorithm reset(); // initialize the starting node weight = Distance()(src_ix, src_iy, dst_ix, dst_iy); start_node = std::make_shared<AStar::Node>(src_ix, src_iy, weight, nullptr); openNodes.push(start_node); // do the algorithm while (!openNodes.empty()) { // list is completely full... we failed if (closedNodes.size() >= MAX_ASTAR_NODES) break; //Get the cheapest open node std::shared_ptr<Node> currentNode = openNodes.top(); openNodes.pop(); // find some child nodes for(const auto& offset: EXPLORE_NODES) { // do not check diagonals if (offset.x != 0 && offset.y != 0) continue; //The node to explore int tmp_x = currentNode->ix + offset.x; int tmp_y = currentNode->iy + offset.y; //Do not explore any node more than once if(closedNodes.find(tmp_x | tmp_y << 16) != closedNodes.end()) { continue; } closedNodes.insert(tmp_x | tmp_y << 16); // check for the simplest case, is this the destination node? if (tmp_x == dst_ix && tmp_y == dst_iy) { weight = Distance()(tmp_x, tmp_y, currentNode->ix, currentNode->iy); final_node = std::make_shared<AStar::Node>(tmp_x, tmp_y, weight, currentNode); return true; } // is the test node on the mesh? Index1D itile = mesh->getTileIndex(Index2D(tmp_x, tmp_y)); if (Index1D::Invalid == itile) { continue; } //Dont walk into pits //@todo: might need to check tile Z level here instead const ego_tile_info_t& ptile = mesh->getTileInfo(itile); if (ptile.isFanOff()) { // add the invalid tile to the list as a closed tile continue; } // is this a wall or impassable? if (mesh->tile_has_bits(Index2D(tmp_x, tmp_y), stoppedby)) { // add the invalid tile to the list as a closed tile continue; } /// /// @todo I need to check for collisions with static objects, like trees // OK. determine the weight (F + H) weight = Distance()(tmp_x, tmp_y, currentNode->ix, currentNode->iy) + Distance()(tmp_x, tmp_y, dst_ix, dst_iy); openNodes.push(std::make_shared<AStar::Node>(tmp_x, tmp_y, weight, currentNode)); } } #ifdef DEBUG_ASTAR if (closedNodes.size() >= MAX_ASTAR_NODES) printf("AStar failed because maximum number of nodes were explored (%d)\n", MAX_ASTAR_NODES); #endif return false; }