Advertisement
Guest User

Maze Generator

a guest
Mar 12th, 2012
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.15 KB | None | 0 0
  1.     #include <cstdlib>
  2.     #include <iostream>
  3.     #include <time.h>
  4.    
  5.     using namespace std;
  6.    
  7.     struct tile{
  8.        
  9.         bool exit;
  10.         tile* west;
  11.         tile* north;
  12.         tile* east;
  13.         tile* south;
  14.        
  15.         tile(){
  16.             exit = false;
  17.             west = NULL;
  18.             north = NULL;
  19.             south = NULL;
  20.             east = NULL;
  21.         };
  22.     };
  23.    
  24.     class maze{
  25.        
  26.     private:
  27.            
  28.        
  29.         static const int max_height = 10;
  30.         static const int max_width = 10;
  31.        
  32.         tile new_maze[max_width][max_height];
  33.        
  34.     public:
  35.        
  36.         maze(){
  37.             init_class_vars();
  38.         };
  39.        
  40.        
  41.         static void init_class_vars(){
  42.            
  43.             static bool first_run = false;
  44.            
  45.             if(!first_run){
  46.                 first_run = true;
  47.                 srand(time(NULL));
  48.             };
  49.            
  50.         };
  51.        
  52.         //generate maze
  53.         void generate_maze(){
  54.             int x;
  55.             int y;
  56.            
  57.             for (x = 0; x < max_width; ++x){
  58.                 for (y = 0; y < max_height; ++y){
  59.                     make_exit(x, y);
  60.                 };
  61.             };
  62.    
  63.             do {
  64.                 reset_exit();           //assume you can't reach any tile
  65.                 run_maze(0, 0);         //run the maze starting at 0, 0
  66.                
  67.             } while (!check_maze());    //check to make sure you can reach all tiles
  68.                                         //if not, this function will make a needed exit
  69.                                         //and try again.
  70.         };
  71.        
  72.         //output maze to console
  73.         void output_maze(){
  74.             int x;
  75.             int y;
  76.            
  77.             string row1;
  78.             string row2;
  79.             string row3;
  80.            
  81.             for (y = 0; y < max_height; ++y){
  82.                 for (x = 0; x < max_width; ++x){
  83.                     row1 = row1 + static_cast<char>(219);
  84.                     row3 = row3 + static_cast<char>(219);
  85.                     if(!new_maze[x][y].north){
  86.                         if(x == 0 && y == 0){
  87.                             row1 = row1 + ' ';
  88.                         } else {
  89.                             row1 = row1 + static_cast<char>(219);
  90.                         }
  91.                     } else {
  92.                         row1 = row1 + ' ';
  93.                     };
  94.                    
  95.                     if(!new_maze[x][y].south){
  96.                         if(x == (max_width - 1) && y == (max_width - 1)){
  97.                             row3 = row3 + ' ';
  98.                         } else {
  99.                             row3 = row3 + static_cast<char>(219);
  100.                         };
  101.                     } else {
  102.                         row3 = row3 + ' ';
  103.                     };
  104.                    
  105.                     if(!new_maze[x][y].west){
  106.                         row2 = row2 + static_cast<char>(219);
  107.                         row2 = row2 + ' ';
  108.                     } else {
  109.                         row2 = row2 + "  ";
  110.                     };
  111.    
  112.                     if(!new_maze[x][y].east){
  113.                         row2 = row2 + static_cast<char>(219);
  114.                     } else {
  115.                         row2 = row2 + ' ';
  116.                     };                
  117.    
  118.                     row1 = row1 + static_cast<char>(219);
  119.                     row3 = row3 + static_cast<char>(219);
  120.                 };
  121.                 row1 = row1 + '\n';
  122.                 row2 = row2 + '\n';
  123.                 row3 = row3 + '\n';
  124.                
  125.                 cout<<row1<<row2<<row3;
  126.                 row1.clear();
  127.                 row2.clear();
  128.                 row3.clear();
  129.             };
  130.         };
  131.    
  132.     private:
  133.        
  134.         //make an exit on a floor tile if one does not already exist.
  135.         bool make_exit(int x, int y){
  136.    
  137.             if(!new_maze[x][y].exit){
  138.                 new_maze[x][y].exit = true;
  139.                 switch (select_direction(x, y)){
  140.                     case 0:  //north
  141.                         new_maze[x][y].north = &new_maze[x][y - 1];
  142.                         new_maze[x][y - 1].south = &new_maze[x][y];
  143.                         make_exit(x, (y - 1));
  144.                         break;
  145.                     case 1:  //south
  146.                         new_maze[x][y].south = &new_maze[x][y + 1];
  147.                         new_maze[x][y + 1].north = &new_maze[x][y];
  148.                         make_exit(x, y + 1);
  149.    
  150.                         break;
  151.                     case 2: //east
  152.                         new_maze[x][y].east = &new_maze[x + 1][y];
  153.                         new_maze[x + 1][y].west = &new_maze[x][y];
  154.                         make_exit((x + 1), y);
  155.    
  156.                         break;
  157.                     case 3: //west
  158.                         new_maze[x][y].west = &new_maze[x - 1][y];
  159.                         new_maze[x - 1][y].east = &new_maze[x][y];
  160.                         make_exit((x - 1), y);
  161.                         break;
  162.                     default:
  163.                         cout<<"Error! direction not recognized!\n";
  164.                         break;
  165.                 };
  166.                
  167.             };
  168.            
  169.            
  170.            
  171.         };
  172.        
  173.         //reset all the exits to false
  174.         void reset_exit(){
  175.             int x;
  176.             int y;
  177.            
  178.             for (x = 0; x < max_width; ++x)
  179.                 for (y = 0; y < max_height; ++y)
  180.                     new_maze[x][y].exit = false;
  181.         };
  182.        
  183.         //run the maze.  Leave a marker in every tile you visit
  184.         void run_maze(int start_x, int start_y){
  185.             run_maze(new_maze[start_x][start_y]);
  186.         };
  187.        
  188.         //run the maze, set every tile you visit to true.
  189.         void run_maze(tile &current_tile){
  190.            
  191.             if(!current_tile.exit){
  192.            
  193.                 current_tile.exit = true;
  194.            
  195.                 if(current_tile.north){
  196.                     run_maze(*current_tile.north);
  197.                 };
  198.                
  199.                 if(current_tile.east){
  200.                     run_maze(*current_tile.east);
  201.                 };
  202.                
  203.                 if(current_tile.south){
  204.                     run_maze(*current_tile.south);
  205.                 };
  206.                
  207.                 if(current_tile.west){
  208.                     run_maze(*current_tile.west);
  209.                 };
  210.    
  211.             };
  212.         };
  213.        
  214.         //Check to make sure every tile has an exit.
  215.         //if we find tiles that cannot be reached, force an exit in the area
  216.         //and return false
  217.        
  218.         //if all tiles have an exit, return true.
  219.         bool check_maze(){
  220.             int x;
  221.             int y;
  222.            
  223.             for (x = 0; x < max_width; ++x){
  224.                 for (y = 0; y < max_height; ++y){
  225.                     if(!new_maze[x][y].exit){
  226.                         while(!force_exit(x, y, select_direction(x, y)));
  227.                         return false;
  228.                     };
  229.                 };
  230.             };
  231.            
  232.             return true;
  233.         };
  234.        
  235.         //force an exit in an area that we can't reach after the maze is initally
  236.         //generated.
  237.         bool force_exit(int x, int y, int direction){
  238.             switch(direction){
  239.                 case 0: //north
  240.                     while(!new_maze[x][y].exit && y != 0){
  241.                         --y;
  242.                     };
  243.                    
  244.                     if(new_maze[x][y].exit){
  245.                         new_maze[x][y].south = &new_maze[x][y + 1];
  246.                         new_maze[x][y + 1].north = &new_maze[x][y];
  247.                         return true;
  248.                     } else {
  249.                         return false;
  250.                     };
  251.                     break;
  252.                 case 1: //south
  253.                
  254.                     while(!new_maze[x][y].exit && y != (max_height - 1)){
  255.                         ++y;
  256.                     };
  257.                    
  258.                     if(new_maze[x][y].exit){
  259.                         new_maze[x][y].north = &new_maze[x][y - 1];
  260.                         new_maze[x][y - 1].south = &new_maze[x][y];
  261.                         return true;
  262.                     } else {
  263.                         return false;
  264.                     };
  265.                     break;
  266.                
  267.                 case 2: //east
  268.                
  269.                     while(!new_maze[x][y].exit && x != (max_width - 1)){
  270.                         ++x;
  271.                     };
  272.                    
  273.                     if(new_maze[x][y].exit){
  274.                         new_maze[x][y].west = &new_maze[x - 1][y];
  275.                         new_maze[x - 1][y].east = &new_maze[x][y];
  276.                         return true;
  277.                     } else {
  278.                         return false;
  279.                     };
  280.                     break;
  281.                 case 3: //west
  282.                
  283.                     while(!new_maze[x][y].exit && x != 0){
  284.                         --x;
  285.                     };
  286.                    
  287.                     if(new_maze[x][y].exit){
  288.                         new_maze[x][y].east = &new_maze[x + 1][y];
  289.                         new_maze[x + 1][y].west = &new_maze[x][y];
  290.                         return true;
  291.                     } else {
  292.                         return false;
  293.                     };
  294.                     break;
  295.                 default:
  296.                     cout<<"Error in force_direction! direction "<<direction<<" unknown!\n";
  297.                     return false;
  298.             };
  299.         };
  300.        
  301.         //select a direction.  If you cannot travel in that direction, pick a new
  302.         //direction.
  303.         int select_direction(int x, int y){
  304.            
  305.             int direction;
  306.            
  307.             //0 = north
  308.             //1 = south
  309.             //2 = east
  310.             //3 = west
  311.            
  312.             while (true){
  313.                 direction = rand() % 4;
  314.                
  315.                 switch(direction){
  316.                     case 0: //north
  317.                         if(y != 0)
  318.                             return direction;
  319.                         break;
  320.                     case 1: //south
  321.                         if(y != (max_height - 1))
  322.                             return direction;
  323.                         break;
  324.                     case 2: //east
  325.                         if(x != (max_width - 1))
  326.                             return direction;
  327.                         break;
  328.                     case 3: //west
  329.                         if(x != 0)
  330.                             return direction;
  331.                         break;
  332.                     default:
  333.                         cout<<"Error in select_direction! Direction "<<direction<<" unknown!\n";
  334.                 };
  335.             };
  336.         };
  337.        
  338.        
  339.        
  340.     };
  341.    
  342.     int main(int argc, char *argv[])
  343.     {
  344.         maze my_maze;
  345.         my_maze.generate_maze();
  346.         my_maze.output_maze();
  347.        
  348.         system("PAUSE");
  349.         return EXIT_SUCCESS;
  350.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement