recursive_division_generator.hxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * HUC - Hurna Core
4  *
5  * Copyright (c) Michael Jeulin-Lagarrigue
6  *
7  * Licensed under the MIT License, you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * https://github.com/Hurna/Hurna-Core/blob/master/LICENSE
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is
13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and limitations under the License.
15  *
16  * The above copyright notice and this permission notice shall be included in all copies or
17  * substantial portions of the Software.
18  *
19  *=========================================================================================================*/
20 #ifndef MODULE_MAZE_DIVISIONG_HXX
21 #define MODULE_MAZE_DIVISIONG_HXX
22 
23 #include <DataStructures/grid.hxx>
24 
25 // STD
26 #include <random>
27 
28 namespace huc
29 {
30  namespace maze
31  {
51  {
52  public:
54  typedef Maze::Cell Cell;
55  typedef Maze::Point Point;
56 
57  std::unique_ptr<Maze> operator()(const uint32_t width, const uint32_t height, const uint32_t seed = 0)
58  {
59  if (width < 1 || height < 1)
60  return nullptr;
61 
62  auto maze(std::unique_ptr<Maze>(new Maze(width, height, true)));
63  std::mt19937 mt(seed); // Initialize random generator (Mersenne Twister)
64 
65  Compute(mt, *maze, Point(0,0), width, height);
66 
67  return maze;
68  }
69 
70  private:
71  static void Compute
72  (std::mt19937& mt, Maze& maze, const Point& origin, const uint32_t width, uint32_t height)
73  {
74  if (width < 2 || height < 2)
75  return;
76 
77  // Build a wall within the room, whether vertical or horizontal,
78  // Open a gate at a random position
79  bool isHorizontalCut = (mt() % 2 == 0) ? true : false; //(width <= height);
80  uint32_t wallIdx = (isHorizontalCut) ? mt() % (height - 1) : mt() % (width - 1);
81  uint32_t pathIdx = (isHorizontalCut) ? mt() % width : mt() % height;
82 
83  // Build wall and Recurse on sub areas (Top and Bottom)
84  if (isHorizontalCut)
85  {
86  maze.DisconnectRow(origin, wallIdx, width, pathIdx);
87  Compute(mt, maze, origin, width, wallIdx + 1);
88  Compute(mt, maze, Point(origin.x, origin.y + wallIdx + 1), width, height - wallIdx - 1);
89  }
90  // Recurse on sub areas (Left and Right)
91  else
92  {
93  maze.DisconnectCol(origin, wallIdx, height, pathIdx);
94  Compute(mt, maze, origin, wallIdx + 1, height);
95  Compute(mt, maze, Point(origin.x + wallIdx + 1, origin.y), width - wallIdx - 1, height);
96  }
97  }
98  };
99  }
100 }
101 
102 #endif // MODULE_MAZE_DIVISIONG_HXX
void DisconnectCol(const Point &origin, const uint32_t idx, const uint32_t height, const uint32_t pathIdx)
Definition: grid.hxx:150
uint32_t x
Definition: grid.hxx:59
static void Compute(std::mt19937 &mt, Maze &maze, const Point &origin, const uint32_t width, uint32_t height)
std::unique_ptr< Maze > operator()(const uint32_t width, const uint32_t height, const uint32_t seed=0)
void DisconnectRow(const Point &origin, const uint32_t idx, const uint32_t width, const uint32_t pathIdx)
Definition: grid.hxx:177
Point struct is a convenient struct use to represent a 2D point for a grid (index position)...
Definition: grid.hxx:56
uint32_t y
Definition: grid.hxx:60