Gistrec

Поиск пути в лабиринте

Feb 14th, 2020
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <array>
  4. #include <queue>
  5. #include <stack>
  6. #include <iomanip>
  7.  
  8. #define х -1
  9. #define о  0
  10.  
  11. enum class SearchType {
  12.     BFS, // Обход в ширину
  13.     DFS  // Обход в глубину
  14. };
  15.  
  16. template <size_t row, size_t col>
  17. using Matrix = std::array<std::array<int, col>, row>;
  18.  
  19. struct Point {
  20.     int x;
  21.     int y;
  22.  
  23.     Point(int x, int y) : x(x), y(y) {};
  24.  
  25.     bool operator==(const Point & other) const {
  26.         return x == other.x && y == other.y;
  27.     }
  28.  
  29.     std::vector<Point> getNearestPoints() const {
  30.         return { Point(x + 1, y), Point(x - 1, y), Point(x, y + 1), Point(x, y - 1) };
  31.     }
  32. };
  33.  
  34. Point get(std::queue<Point>& container) { return container.front(); }
  35. Point get(std::stack<Point>& container) { return container.top();   }
  36.  
  37. template <SearchType type, typename Labyrinth>
  38. bool search(Labyrinth & labyrinth, Point start, Point end) {
  39.     using ContainerType = std::conditional_t<type == SearchType::BFS, std::queue<Point>, std::stack<Point>>;
  40.    
  41.     ContainerType queue;
  42.    
  43.     labyrinth[start.x][start.y] = 1;
  44.     queue.push(start);
  45.  
  46.     while (!queue.empty()) {
  47.         const Point point = get(queue);
  48.         queue.pop();
  49.  
  50.         const int value = labyrinth[point.x][point.y];
  51.        
  52.         if (point == end) return true;
  53.  
  54.         // Обходим соседние вершины
  55.         for (const auto near : point.getNearestPoints()) {
  56.             if (labyrinth[near.x][near.y] == 0) {
  57.                 labyrinth[near.x][near.y] = value + 1;
  58.                 std::cout << "Add " << near.x << " " << near.y << std::endl;
  59.                 queue.push(near);
  60.             }
  61.         }
  62.     }
  63.     return false;
  64. }
  65.  
  66. template <typename Matrix>
  67. std::vector<Point> getPath(const Matrix& labyrinth, Point end) {
  68.     std::vector<Point> path;
  69.     path.reserve(labyrinth[end.x][end.y]);
  70.  
  71.     Point current = end;
  72.  
  73.     while (labyrinth[current.x][current.y] != 1) {
  74.         const int find = labyrinth[current.x][current.y] - 1;
  75.  
  76.         for (const auto near : current.getNearestPoints()) {
  77.             if (labyrinth[near.x][near.y] == find) {
  78.                 path.push_back(near);
  79.                 current = near;
  80.                 break;
  81.             }
  82.         }
  83.     }
  84.  
  85.     path.push_back(end);
  86.  
  87.     std::reverse(path.begin(), path.end());
  88.  
  89.     return path;
  90. }
  91.  
  92. int main() {
  93.     constexpr size_t row = 7U;
  94.     constexpr size_t col = 6U;
  95.  
  96.     Matrix<row, col> labyrinth = {{
  97.         { х, х, х, х, х, х},
  98.         { х, о, о, о, о, х},
  99.         { х, о, о, о, о, х},
  100.         { х, о, о, о, о, х},
  101.         { х, о, о, о, о, х},
  102.         { х, о, о, о, о, х},
  103.         { х, х, х, х, х, х}
  104.     }};
  105.  
  106.     Point start(3, 3);
  107.     Point end(1, 1);
  108.  
  109.     auto result = search<SearchType::DFS>(labyrinth, start, end);
  110.  
  111.     for (auto row : labyrinth) {
  112.         for (auto cols : row) {
  113.             std::cout << std::setw(3) << cols;
  114.         }
  115.         std::cout << std::endl;
  116.     }
  117.  
  118.     if (result) {
  119.         auto path = getPath(labyrinth, end);
  120.         for (const auto point : path) {
  121.             std::cout << point.x << " " << point.y << std::endl;
  122.         }
  123.     }
  124.  
  125.     return 0;
  126. }
Add Comment
Please, Sign In to add comment