maker_memory.hpp

Go to the documentation of this file.
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 SourceForge.net. Use the Table of Contents for navigation.