00001 00027 #ifndef MSMAZES_CORE_MAZE_MAKER_MEMORY_HPP 00028 #define MSMAZES_CORE_MAZE_MAKER_MEMORY_HPP 00029 00030 // std::vector 00031 #include <vector> 00032 // std::random_shuffle 00033 #include <algorithm> 00034 // boost::mpl::true_ and boost::mpl::false_ 00035 #include <boost/mpl/bool.hpp> 00036 // boost::mpl::void_ 00037 #include <boost/mpl/void.hpp> 00038 // boost::tie 00039 #include <boost/utility.hpp> 00040 // boost::property_map, boost::get, and boost::put 00041 #include <boost/property_map.hpp> 00042 // boost::random_number_generator 00043 #include <boost/random/random_number_generator.hpp> 00044 // boost::graph_traits 00045 #include <boost/graph/graph_traits.hpp> 00046 // boost::vertex_index_t and boost::vertex_index1_t 00047 #include <boost/graph/properties.hpp> 00048 //#include <boost/graph/adjacency_list.hpp> must be included before this file. 00049 00050 namespace msmazes { 00051 00053 00074 struct MemoryMazeMaker 00075 { 00079 typedef boost::mpl::void_ 00080 DefaultPolicy; 00081 00085 typedef boost::mpl::true_ 00086 RequiresRandomInputs; 00087 00091 typedef boost::mpl::true_ 00092 RestartsOnDeadEnd; 00093 00098 typedef boost::mpl::false_ 00099 BuildsLastVisitedMap; 00100 00106 template < 00107 typename MazeStructType 00108 , typename Pattern 00109 , typename RNGEngine 00110 , typename MazePolicy 00111 > 00112 static void 00113 makeMaze( 00114 MazeStructType& maze 00115 , const Pattern& pattern 00116 , RNGEngine& rng_engine 00117 , const MazePolicy& policy 00118 ) 00119 { 00120 typedef typename Pattern::Graph 00121 BaseGraph; 00122 typedef boost::graph_traits<BaseGraph> 00123 BaseGraphTraits; 00124 typedef typename BaseGraphTraits::vertex_descriptor 00125 BaseVertex; 00126 typedef typename BaseGraphTraits::vertices_size_type 00127 BaseIndex; 00128 typedef std::vector<BaseIndex> 00129 BaseIndexVector; 00130 typedef typename BaseIndexVector::size_type 00131 VectorIndex; 00132 typedef boost::random_number_generator<RNGEngine,VectorIndex> 00133 Shuffler; 00134 typedef typename MazeStructType::Graph 00135 MazeGraph; 00136 typedef boost::graph_traits<MazeGraph> 00137 MazeGraphTraits; 00138 typedef typename MazeGraphTraits::vertex_descriptor 00139 MazeVertex; 00140 00141 const BaseGraph& base_graph = pattern.getGraph(); 00142 00143 BaseIndex 00144 base_index; 00145 BaseIndexVector 00146 index_vector; 00147 typename boost::property_map<BaseGraph,boost::vertex_index_t>::type 00148 in_index_map = boost::get(boost::vertex_index_t(), base_graph); 00149 typename BaseGraphTraits::vertex_iterator 00150 in_vi, in_vend; 00151 00152 for ( 00153 boost::tie(in_vi, in_vend) = boost::vertices(base_graph); 00154 in_vi != in_vend; 00155 ++in_vi 00156 ) 00157 { 00158 base_index = boost::get(in_index_map, *in_vi); 00159 index_vector.push_back(base_index); 00160 } 00161 00162 MazeGraph& maze_graph = maze.getGraph(); 00163 Shuffler shuffler(rng_engine); 00164 00165 std::random_shuffle(index_vector.begin(), index_vector.end(), shuffler); 00166 base_index = boost::num_vertices(base_graph); 00167 ++base_index; 00168 ++base_index; 00169 00170 while (boost::num_vertices(maze_graph) < base_index) 00171 { 00172 boost::add_vertex(maze_graph); 00173 } 00174 00175 typename MazeGraphTraits::vertices_size_type 00176 maze_vertex_count = boost::num_vertices(maze_graph); 00177 MazeVertex 00178 out_vertex = MazeGraphTraits::null_vertex(); 00179 00180 while (maze_vertex_count > base_index) 00181 { 00182 out_vertex = boost::vertex(--maze_vertex_count, maze_graph); 00183 boost::clear_vertex(out_vertex, maze_graph); 00184 boost::remove_vertex(out_vertex, maze_graph); 00185 } 00186 00187 MazeVertex in_vertex = boost::vertex(0, maze_graph); 00188 00189 maze.setSourceVertex(in_vertex); 00190 out_vertex = boost::vertex(--maze_vertex_count, maze_graph); 00191 maze.setTargetVertex(out_vertex); 00192 boost::clear_vertex(out_vertex, maze_graph); 00193 00194 while (maze_vertex_count > 0) 00195 { 00196 boost::clear_vertex( 00197 boost::vertex(--maze_vertex_count, maze_graph) 00198 , maze_graph 00199 ); 00200 } 00201 00202 typename boost::property_map<MazeGraph,boost::vertex_index1_t>::type 00203 out_parent_map = boost::get(boost::vertex_index1_t(), maze_graph); 00204 VectorIndex 00205 vector_index = VectorIndex(); 00206 00207 boost::put(out_parent_map, out_vertex, pattern.getCellCount()); 00208 base_index = index_vector[vector_index]; 00209 boost::put(out_parent_map, in_vertex, base_index); 00210 in_vertex = boost::vertex(base_index + 1, maze_graph); 00211 boost::put(out_parent_map, in_vertex, base_index); 00212 boost::add_edge(maze.getSourceVertex(), in_vertex, maze_graph); 00213 00214 while (++vector_index < index_vector.size()) 00215 { 00216 base_index = index_vector[vector_index]; 00217 out_vertex = boost::vertex(base_index + 1, maze_graph); 00218 boost::add_edge(in_vertex, out_vertex, maze_graph); 00219 boost::put(out_parent_map, out_vertex, base_index); 00220 in_vertex = out_vertex; 00221 } 00222 00223 boost::add_edge(out_vertex, maze.getTargetVertex(), maze_graph); 00224 } 00225 }; 00226 } // namespace msmazes 00227 00228 #endif /* MSMAZES_CORE_MAZE_MAKER_MEMORY_HPP */
Multi-State Mazes in C++ is hosted by . Use the Table of Contents for navigation.