Advertisement
daniv1

Untitled

Mar 13th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4. #include <random>
  5.  
  6. class MazeGenerator
  7. {
  8. public:
  9.     static std::shared_ptr<std::vector<std::vector<char>>> generate(unsigned width, unsigned height)
  10.     {
  11.         if ((width < 1) || (height < 1))
  12.             return nullptr;
  13.  
  14.         const auto top_limit = std::numeric_limits<unsigned>::max();
  15.  
  16.         if (((top_limit - 1) / 2 <= width) || ((top_limit - 1) / 2 <= height))
  17.             return nullptr;
  18.  
  19.         const unsigned output_height = height * 2 + 1;
  20.         const unsigned output_width = width * 2 + 1;
  21.  
  22.         auto maze = std::make_shared<std::vector<std::vector<char>>>();
  23.  
  24.         maze.get()->reserve(output_height);
  25.  
  26.  
  27.         for (unsigned i = 0; i < output_height; ++i)
  28.         {
  29.             std::vector<char> row;
  30.             row.reserve(output_width);
  31.             for (unsigned j = 0; j < output_width; ++j)
  32.  
  33.                 if ((i % 2 == 1) && (j % 2 == 1))
  34.                     row.push_back(' ');
  35.                 else
  36.  
  37.                     if (((i % 2 == 1) && (j % 2 == 0) && (j != 0) && (j != output_width - 1)) ||
  38.                         ((j % 2 == 1) && (i % 2 == 0) && (i != 0) && (i != output_height - 1)))
  39.                         row.push_back(' ');
  40.                     else
  41.                         row.push_back('#');
  42.             maze.get()->push_back(std::move(row));
  43.         }
  44.  
  45.  
  46.         std::vector<unsigned> row_set;
  47.         row_set.reserve(width);
  48.  
  49.         for (unsigned i = 0; i < width; ++i)
  50.             row_set.push_back(0);
  51.         unsigned set = 1;
  52.         std::random_device rd;
  53.         std::mt19937 mt(rd());
  54.  
  55.         std::uniform_int_distribution<int> dist(0, 2);
  56.  
  57.         for (unsigned i = 0; i < height; ++i)
  58.         {
  59.             for (unsigned j = 0; j < width; ++j)
  60.                 if (row_set[j] == 0)
  61.                     row_set[j] = set++;
  62.  
  63.  
  64.             for (unsigned j = 0; j < width - 1; ++j)
  65.             {
  66.  
  67.                 const auto right_wall = dist(mt);
  68.  
  69.                 if ((right_wall == 1) || (row_set[j] == row_set[j + 1]))
  70.                     maze.get()->at(i * 2 + 1).at(j * 2 + 2) = '#';
  71.                 else
  72.                 {
  73.  
  74.                     const auto changing_set = row_set[j + 1];
  75.                     for (unsigned l = 0; l < width; ++l)
  76.                         if (row_set[l] == changing_set)
  77.                             row_set[l] = row_set[j];
  78.                 }
  79.             }
  80.  
  81.             for (unsigned j = 0; j < width; ++j)
  82.             {
  83.                 const auto bottom_wall = dist(mt);
  84.                 unsigned int count_current_set = 0;
  85.                 for (unsigned l = 0; l < width; ++l)
  86.                     if (row_set[j] == row_set[l])
  87.                         count_current_set++;
  88.                 if ((bottom_wall == 1) && (count_current_set != 1))
  89.                     maze.get()->at(i * 2 + 2).at(j * 2 + 1) = '#';
  90.             }
  91.  
  92.             if (i != height - 1)
  93.             {
  94.  
  95.                 for (unsigned j = 0; j < width; ++j) {
  96.                     unsigned count_hole = 0;
  97.                     for (unsigned l = 0; l < width; ++l)
  98.                         if ((row_set[l] == row_set[j]) && (maze.get()->at(i * 2 + 2).at(l * 2 + 1) == ' '))
  99.                             count_hole++;
  100.                     if (count_hole == 0)
  101.                         maze.get()->at(i * 2 + 2).at(j * 2 + 1) = ' ';
  102.                 }
  103.  
  104.                 for (unsigned j = 0; j < width; ++j)
  105.                     if (maze.get()->at(i * 2 + 2).at(j * 2 + 1) == '#')
  106.                         row_set[j] = 0;
  107.             }
  108.         }
  109.         for (unsigned int j = 0; j < width - 1; ++j)
  110.         {
  111.             if (row_set[j] != row_set[j + 1])
  112.                 maze.get()->at(output_height - 2).at(j * 2 + 2) = ' ';
  113.         }
  114.         return maze;
  115.     }
  116.  
  117.     static void print(const std::shared_ptr<std::vector<std::vector<char>>>& maze)
  118.     {
  119.         if (maze == nullptr)
  120.             return;
  121.  
  122.         for (unsigned i = 0; i < maze.get()->size(); ++i)
  123.         {
  124.             for (unsigned j = 0; j < maze.get()->at(0).size(); ++j)
  125.                 std::cout << maze.get()->at(i).at(j);
  126.             std::cout << std::endl;
  127.         }
  128.     }
  129.  
  130.  
  131. private:
  132.     MazeGenerator() = default;
  133. };
  134. int main()
  135. {
  136.     std::shared_ptr<std::vector<std::vector<char>>> mg = MazeGenerator::generate(12,8);
  137.     MazeGenerator::print(mg);
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement