Guest User

Untitled

a guest
Jun 18th, 2018
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.00 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <string>
  4. #include <cstdlib>
  5. #include <time.h>
  6.  
  7. using namespace std;
  8.  
  9. #define BYTE unsigned char
  10.  
  11. // wall & visited flag vales
  12. const BYTE CELL_TOP = 1;
  13. const BYTE CELL_BOTTOM = 2;
  14. const BYTE CELL_LEFT = 4;
  15. const BYTE CELL_RIGHT = 8;
  16. const BYTE CELL_VISITED = 16;
  17.  
  18. // maze dimensions
  19. const int MAZE_ROWS = 3;
  20. const int MAZE_COLS = 3;
  21.  
  22.  
  23. // starting cell
  24. const int START_CELL_ROW = 0;
  25. const int START_CELL_COL = 0;
  26. const int START_WALL = CELL_LEFT;
  27.  
  28. // ending cell
  29. const int END_CELL_ROW = 2;
  30. const int END_CELL_COL = 2;
  31. const int END_WALL = CELL_RIGHT;
  32.  
  33. // location indexes
  34. const int CELL_ROW_INDEX = 0;
  35. const int CELL_COL_INDEX = 1;
  36.  
  37.  
  38. // maze print characters
  39. const char OUT_TOP_LEFT = '-';
  40. const char OUT_TOP_MID = '-';
  41. const char OUT_TOP_RIGHT = '-';
  42. const char OUT_SIDE_LEFT = '|';
  43. const char OUT_SIDE_RIGHT = '|';
  44. const char OUT_BOT_LEFT = '-';
  45. const char OUT_BOT_MID = '-';
  46. const char OUT_BOT_RIGHT = '-';
  47. const char INSIDE_MIDDLE = '+';
  48. const char CELL_TOP_BOT = '-';
  49. const char CELL_LEFT_RIGHT = '|';
  50. const char CELL_OPEN_HORZ = ' ';
  51. const char CELL_OPEN_VERT = ' ';
  52. const char CELL_VISITIED_ON = '.';
  53. const char CELL_VISITIED_OFF = ' ';
  54.  
  55. // function declarations
  56. bool hasUnvisitedCells(BYTE cells[][MAZE_COLS]);
  57. bool hasAvailableNeighbors(BYTE cells[][MAZE_COLS], int location[]);
  58. void chooseRandomNeighbor(BYTE cells[][MAZE_COLS], int current[], int neighbor[]);
  59. void removeWalls(BYTE cells[][MAZE_COLS], int current[], int neighbor[]);
  60. void initMaze(BYTE cells[][MAZE_COLS]);
  61. int pushStack(int stack[][2], int location[], int stackPoint);
  62. void popStack(int stack[][2], int location[], int& stackPoint);
  63. void copyOneLocTwo(int locOne[], int locTwo[]);
  64. void printMaze(BYTE cells[][MAZE_COLS]);
  65. void printMazeDebug(BYTE cells[][MAZE_COLS]);
  66.  
  67.  
  68. int main() {
  69.     char tmp;                           // pause program
  70.  
  71.                                         // init random generator
  72.     srand(time(NULL));                  // stdlib; time.h
  73.  
  74.     // sotrage for the maze cells
  75.     BYTE maze[MAZE_ROWS][MAZE_COLS] = { 0 };
  76.  
  77.     // storage for our stack of visited cells
  78.     int stack[MAZE_ROWS * MAZE_COLS][2] = { 0 };
  79.  
  80.     int stackPointer = -1;              // empty stack value
  81.  
  82.     initMaze(maze);
  83.  
  84.     // set starting cell
  85.     int startCell[2];
  86.     startCell[CELL_ROW_INDEX] = START_CELL_ROW;
  87.     startCell[CELL_COL_INDEX] = START_CELL_COL;
  88.     // turn off starting wall
  89.     maze[startCell[CELL_ROW_INDEX]][startCell[CELL_COL_INDEX]] ^= START_WALL;
  90.  
  91.     // turn off ending wall
  92.     maze[END_CELL_ROW][END_CELL_COL] ^= END_WALL;
  93.  
  94.     printMaze(maze);
  95.  
  96.     cout << endl;
  97.  
  98.     printMazeDebug(maze);
  99.  
  100.     cout << endl;
  101.  
  102.     cin >> tmp;
  103.  
  104.     // 1. Make the inital cell the current cell and mark it as visited
  105.     int currentCell[2];
  106.     copyOneLocTwo(startCell, currentCell);
  107.     // mark visited flag
  108.     maze[currentCell[CELL_ROW_INDEX]][currentCell[CELL_COL_INDEX]] ^= CELL_VISITED;
  109.  
  110.  
  111.     // 2. While there are unvisited cells
  112.     while (hasUnvisitedCells(maze)) {
  113.  
  114.         // i. if the current cell has any neighbors which have not been visited
  115.         if (hasAvailableNeighbors(maze, currentCell)) {
  116.  
  117.             // 1. Chose randomly one of the unvisited neighbors
  118.             int neighborCell[2] = { 0 };
  119.             chooseRandomNeighbor(maze, currentCell, neighborCell);
  120.  
  121.             // 2. Push the current cell to the stack
  122.             stackPointer = pushStack(stack, currentCell, stackPointer);
  123.  
  124.             // 3. Remove the wall between the current cell and the chosen cell
  125.             removeWalls(maze, currentCell, neighborCell);
  126.  
  127.             // 4. Make the chosen cell the current cell and mark it as visited
  128.             copyOneLocTwo(neighborCell, currentCell);
  129.             // mark visited flag
  130.             maze[currentCell[CELL_ROW_INDEX]][currentCell[CELL_COL_INDEX]] ^= CELL_VISITED;
  131.  
  132.             // 5. Print the Maze
  133.             printMaze(maze);
  134.             cout << endl;
  135.  
  136.             printMazeDebug(maze);
  137.             cout << endl;
  138.  
  139.             cin >> tmp;
  140.  
  141.         } // end has any neighbors
  142.  
  143.           // ii. Else if the stack is not empty
  144.         else if (stackPointer > -1) {
  145.  
  146.             // Pop the last cell from the stack and make it the current cell
  147.             popStack(stack, currentCell, stackPointer);
  148.  
  149.         }
  150.  
  151.  
  152.     } // end while there are unvisitied cells
  153.  
  154.  
  155.       // 3. Print the Maze
  156.     printMaze(maze);
  157.     cout << endl;
  158.  
  159.     printMazeDebug(maze);
  160.     cout << endl;
  161.  
  162.     // pause program
  163.     cin >> tmp;
  164.  
  165.     return 0;
  166. } // end main
  167.  
  168.   /***/
  169. bool hasUnvisitedCells(BYTE cells[][MAZE_COLS]) {
  170.  
  171.     bool isVisited = true;
  172.  
  173.     int row = 0;
  174.  
  175.  
  176.     while (isVisited && row < MAZE_ROWS) {
  177.  
  178.         int col = 0;
  179.         while (isVisited && col < MAZE_COLS) {
  180.  
  181.             isVisited = cells[row][col] & CELL_VISITED;
  182.             col++;
  183.         }
  184.  
  185.         row++;
  186.     }
  187.  
  188.     return !isVisited;
  189. }
  190.  
  191.  
  192. /**
  193. * Checks to see if there are any available neigbors
  194. * @param cells - the maze
  195. * @param location - the position of the cells
  196. */
  197. bool hasAvailableNeighbors(BYTE cells[][MAZE_COLS], int location[]) {
  198.     // check if has neighbor above
  199.  
  200.     if (location[CELL_ROW_INDEX] > 0) {
  201.         // check if not visited
  202.         if (!(cells[location[CELL_ROW_INDEX] - 1][location[CELL_COL_INDEX]] & CELL_VISITED)) {
  203.             return true;
  204.         }
  205.     }
  206.  
  207.     // check if has neighbor below
  208.  
  209.     if (location[CELL_ROW_INDEX] < MAZE_ROWS - 1) {
  210.         // check if not visited
  211.         if (!(cells[location[CELL_ROW_INDEX] + 1][location[CELL_COL_INDEX]] & CELL_VISITED)) {
  212.             return true;
  213.         }
  214.     }
  215.  
  216.     // check if has left neighbor
  217.  
  218.     if (location[CELL_COL_INDEX] > 0) {
  219.         // check if not visited
  220.         if (!(cells[location[CELL_ROW_INDEX]][location[CELL_COL_INDEX] - 1] & CELL_VISITED)) {
  221.             return true;
  222.         }
  223.     }
  224.  
  225.     // check if has right neighbor
  226.  
  227.     if (location[CELL_COL_INDEX] < MAZE_COLS - 1) {
  228.         // check if not visited
  229.         if (!(cells[location[CELL_ROW_INDEX]][location[CELL_COL_INDEX] + 1] & CELL_VISITED)) {
  230.             return true;
  231.         }
  232.     }
  233.  
  234.     return false;
  235.  
  236. } // end hasAvailableNeighbors
  237.  
  238.  
  239.   /**
  240.   * Chooses a random neighbor in the maze
  241.   * @param cells - the maze
  242.   * @param current - the current position of the maze
  243.   * @param neighbor - the position of the neighbor
  244.   */
  245. void chooseRandomNeighbor(BYTE cells[][MAZE_COLS], int current[], int neighbor[]) {
  246.  
  247.     bool done = false;
  248.  
  249.     while (!done) {
  250.         int randNeighbor = rand() % 4;      // random 0 through 3
  251.  
  252.         switch (randNeighbor) {
  253.  
  254.         case 0:                     // TOP
  255.             if (current[CELL_ROW_INDEX] > 0) {
  256.                 if (!(cells[current[CELL_ROW_INDEX] - 1][current[CELL_COL_INDEX]] & CELL_VISITED)) {
  257.  
  258.                     neighbor[CELL_ROW_INDEX] = current[CELL_ROW_INDEX] - 1;
  259.                     neighbor[CELL_COL_INDEX] = current[CELL_COL_INDEX];
  260.  
  261.                     done = true;
  262.  
  263.                 }
  264.             }
  265.             break;
  266.  
  267.         case 1:                     // BOTTOM
  268.             if (current[CELL_ROW_INDEX] < MAZE_ROWS - 1) {
  269.                 if (!(cells[current[CELL_ROW_INDEX] + 1][current[CELL_COL_INDEX]] & CELL_VISITED)) {
  270.  
  271.                     neighbor[CELL_ROW_INDEX] = current[CELL_ROW_INDEX] + 1;
  272.                     neighbor[CELL_COL_INDEX] = current[CELL_COL_INDEX];
  273.  
  274.                     done = true;
  275.  
  276.                 }
  277.             }
  278.             break;
  279.  
  280.         case 2:                     // LEFT
  281.             if (current[CELL_COL_INDEX] > 0) {
  282.                 if (!(cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX] - 1] & CELL_VISITED)) {
  283.  
  284.                     neighbor[CELL_ROW_INDEX] = current[CELL_ROW_INDEX];
  285.                     neighbor[CELL_COL_INDEX] = current[CELL_COL_INDEX] - 1;
  286.  
  287.                     done = true;
  288.                 }
  289.             }
  290.             break;
  291.  
  292.         case 3:                     // RIGHT
  293.             if (current[CELL_COL_INDEX] < MAZE_COLS - 1) {
  294.                 if (!(cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX] + 1] & CELL_VISITED)) {
  295.  
  296.                     neighbor[CELL_ROW_INDEX] = current[CELL_ROW_INDEX];
  297.                     neighbor[CELL_COL_INDEX] = current[CELL_COL_INDEX] + 1;
  298.  
  299.                     done = true;
  300.  
  301.                 }
  302.             }
  303.             break;
  304.  
  305.         } // end switch
  306.  
  307.  
  308.     }
  309.  
  310. } //end chooseRandomNeighbor
  311.  
  312.  
  313.   /**
  314.   * Remove the wall between the current cell and the chosen cell
  315.   * @param cells - the maze
  316.   * @param current - the current position of the maze
  317.   * @param neighbor - the position of the neighbor
  318.   */
  319. void removeWalls(BYTE cells[][MAZE_COLS], int current[], int neighbor[]) {
  320.  
  321.     // test for the location of current and neighbor
  322.  
  323.     // test for neighbor above
  324.     if (neighbor[CELL_ROW_INDEX] < current[CELL_ROW_INDEX]) {
  325.  
  326.         cells[neighbor[CELL_ROW_INDEX]][neighbor[CELL_COL_INDEX]] ^= CELL_BOTTOM;   // toggle wall off
  327.         cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX]] ^= CELL_TOP;
  328.     }
  329.  
  330.  
  331.     // test for neighbor below
  332.  
  333.     else if (neighbor[CELL_ROW_INDEX] > current[CELL_ROW_INDEX]) {
  334.  
  335.         cells[neighbor[CELL_ROW_INDEX]][neighbor[CELL_COL_INDEX]] ^= CELL_TOP;      // toggle wall off
  336.         cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX]] ^= CELL_BOTTOM;
  337.     }
  338.  
  339.     // test for neighbor left
  340.  
  341.     else if (neighbor[CELL_COL_INDEX] < current[CELL_COL_INDEX]) {
  342.  
  343.         cells[neighbor[CELL_ROW_INDEX]][neighbor[CELL_COL_INDEX]] ^= CELL_RIGHT;    // toggle wall off
  344.         cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX]] ^= CELL_LEFT;
  345.     }
  346.  
  347.     // neighbor must be right
  348.  
  349.     else {
  350.  
  351.         cells[neighbor[CELL_ROW_INDEX]][neighbor[CELL_COL_INDEX]] ^= CELL_LEFT;     // toggle wall off
  352.         cells[current[CELL_ROW_INDEX]][current[CELL_COL_INDEX]] ^= CELL_RIGHT;
  353.  
  354.     }
  355. } // end removeWalls
  356.  
  357.  
  358.   /**
  359.   * Initialize maze array elements to turn all
  360.   * walls on and visited off
  361.   * @param cells - the grid of cells in the maze
  362.   */
  363. void initMaze(BYTE cells[][MAZE_COLS]) {
  364.  
  365.     for (int row = 0; row < MAZE_ROWS; row++) {
  366.  
  367.         for (int col = 0; col < MAZE_COLS; col++) {
  368.             cells[row][col] = CELL_TOP | CELL_BOTTOM | CELL_LEFT | CELL_RIGHT;
  369.         }
  370.     }
  371.  
  372. }
  373.  
  374.  
  375. /*
  376. * Adds a cell location onto the stack
  377. * @param stack - the location stack
  378. * @param location - row and col of a maze cell
  379. * @param stackPoint - last location added to the stack
  380. * @return int - new stack pointer
  381. */
  382. int pushStack(int stack[][2], int location[], int stackPoint) {
  383.     int spNew = stackPoint;
  384.  
  385.     spNew++;                    // move sp up the stack
  386.     copyOneLocTwo(location, stack[spNew]);
  387.  
  388.     return spNew;
  389.  
  390. }
  391.  
  392.  
  393. /*
  394. * Pull a cell location off the stack
  395. * @param stack - the location stack
  396. * @param location - row and col of a maze cell
  397. * @param stackPoint - last location added to the stack and return new
  398. */
  399. void popStack(int stack[][2], int location[], int& stackPoint) {
  400.  
  401.     copyOneLocTwo(stack[stackPoint], location);
  402.     stackPoint--;
  403.  
  404.  
  405. }
  406.  
  407.  
  408. /*
  409. * Copies the contents of one location to another
  410. * @param locOne - one location
  411. * @param locTwo - another location
  412. */
  413. void copyOneLocTwo(int locOne[], int locTwo[]) {
  414.  
  415.     locTwo[CELL_ROW_INDEX] = locOne[CELL_ROW_INDEX];
  416.     locTwo[CELL_COL_INDEX] = locOne[CELL_COL_INDEX];
  417. }
  418.  
  419.  
  420. /**
  421. * Printing the maze to the console
  422. * @param cells - the grid of cells in the maze
  423. */
  424. void printMaze(BYTE cells[][MAZE_COLS]) {
  425.  
  426.     for (int row = 0; row < MAZE_ROWS; row++) {
  427.  
  428.         // print the top row of the cells
  429.         for (int col = 0; col < MAZE_COLS; col++) {
  430.  
  431.             /*** print left spacer ***/
  432.  
  433.             // are we on the top row
  434.             if (row == 0) {
  435.  
  436.                 // are we on the left wall
  437.                 if (col == 0) {
  438.  
  439.  
  440.  
  441.                     cout << OUT_TOP_LEFT;
  442.                 }
  443.                 else {
  444.                     cout << OUT_TOP_MID;
  445.                 }
  446.  
  447.             }
  448.  
  449.             else { // not on top row
  450.  
  451.                    // are we on the left wall
  452.                 if (col == 0) {
  453.  
  454.  
  455.  
  456.                     cout << OUT_SIDE_LEFT;
  457.                 }
  458.                 else {
  459.                     cout << INSIDE_MIDDLE;
  460.                 }
  461.  
  462.             }
  463.  
  464.             // print top left spacer
  465.  
  466.             /*** print cell top ***/
  467.  
  468.             if (cells[row][col] & CELL_TOP) {
  469.                 cout << CELL_TOP_BOT;
  470.             }
  471.             else {
  472.                 cout << CELL_OPEN_HORZ;
  473.             }
  474.  
  475.             // print last right spacer
  476.             if (col == MAZE_COLS - 1) {
  477.  
  478.                 //top row
  479.                 if (row == 0) {
  480.                     cout << OUT_TOP_RIGHT;
  481.                 }
  482.                 else { // not top row
  483.                     cout << OUT_SIDE_RIGHT;
  484.                 }
  485.             }
  486.  
  487.  
  488.         } //print top row
  489.  
  490.           // move down to start printing side walls
  491.         cout << endl;
  492.  
  493.         // print side walls of the cells
  494.         for (int col = 0; col < MAZE_COLS; col++) {
  495.  
  496.             // prints cell left side wall
  497.             if (cells[row][col] & CELL_LEFT) {
  498.                 cout << CELL_LEFT_RIGHT;
  499.  
  500.             }
  501.             else {
  502.                 cout << CELL_OPEN_VERT;
  503.             }
  504.  
  505.             // print cell visited
  506.             if (cells[row][col] & CELL_VISITED) {
  507.                 cout << CELL_VISITIED_ON;
  508.  
  509.             }
  510.             else {
  511.                 cout << CELL_VISITIED_OFF;
  512.             }
  513.  
  514.             // print right wall
  515.             if (col == MAZE_COLS - 1) {
  516.  
  517.                 // prints cell right side wall
  518.                 if (cells[row][col] & CELL_RIGHT) {
  519.                     cout << CELL_LEFT_RIGHT;
  520.  
  521.                 }
  522.                 else {
  523.                     cout << CELL_OPEN_VERT;
  524.                 }
  525.             }
  526.  
  527.  
  528.         } // print side walls
  529.  
  530.           // move down to start printing next top walls
  531.         cout << endl;
  532.  
  533.         // print bottom row
  534.         if (row == MAZE_ROWS - 1) {
  535.  
  536.             // print the bottom row of the cell walls
  537.             for (int col = 0; col < MAZE_COLS; col++) {
  538.  
  539.                 // print spacer
  540.                 if (col == 0) {
  541.                     cout << OUT_BOT_LEFT;
  542.                 }
  543.                 else {
  544.                     cout << OUT_BOT_MID;
  545.                 }
  546.  
  547.                 // print cell bottom wall
  548.                 if (cells[row][col] & CELL_BOTTOM) {
  549.                     cout << CELL_TOP_BOT;
  550.                 }
  551.                 else {
  552.                     cout << CELL_OPEN_HORZ;
  553.                 }
  554.  
  555.                 // print right corner
  556.                 if (col == MAZE_COLS - 1) {
  557.                     cout << OUT_BOT_RIGHT;
  558.                 }
  559.  
  560.             } // bottom walls
  561.  
  562.  
  563.               // end the cells
  564.             cout << endl;
  565.  
  566.         } // bottom row
  567.  
  568.  
  569.     } // end row loop
  570.  
  571. } // end printMaze
  572.  
  573.  
  574.  
  575.   /**
  576.   * Printing the maze call values to the console
  577.   * @param cells - the grid of cells in the maze
  578.   */
  579. void printMazeDebug(BYTE cells[][MAZE_COLS]) {
  580.  
  581.     for (int row = 0; row < MAZE_ROWS; row++) {
  582.  
  583.         for (int col = 0; col < MAZE_COLS; col++) {
  584.  
  585.             cout << to_string(int(cells[row][col])) << " ";
  586.         }
  587.  
  588.         cout << endl;
  589.     }
  590.  
  591. }
Advertisement
Add Comment
Please, Sign In to add comment