Advertisement
Zabari

MazeSolver

Nov 6th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.08 KB | None | 0 0
  1. //Name: Stephen Ku
  2. //Created on: 10/29/18
  3. //Title: Project 4
  4. //Due Date: 11/6/2018 12PM
  5. //Course: CSCI 235
  6.  
  7. #include "MazeSolver.h"
  8. #include <string>
  9. #include <fstream>
  10. #include <iostream>
  11. #include <array>
  12. #include <stack>
  13.  
  14. //constructor
  15. //pre: input file is in correct format with first two values being integers
  16. //      followed by valid maze characters in {'_', '*','$'}
  17. //post: if input file cannot be read outputs "Cannot read from input_file"
  18. //      otherwise sets maze_rows_ and maze_columns_ from the first two values in input file
  19. //      and allocates two 2-dimesional array of size maze_rows_ and maze_columns_
  20. //      both maze_ and solution_ are initialized with characters read from input
  21. MazeSolver::MazeSolver(std::string input_file)
  22. {
  23.     Position pos;
  24.     pos.row = 0;
  25.     pos.column = 0;
  26.     std::ifstream in_stream;
  27.     in_stream.open(input_file);
  28.     if(!in_stream.is_open())
  29.     {
  30.         std::cout << "Cannot read from " << input_file << std::endl;
  31.     }
  32.     else
  33.     {
  34.         in_stream >> maze_rows_;
  35.         in_stream >> maze_columns_;
  36.         // std::cout << maze_rows_ << std::endl;
  37.         initializeMaze(maze_rows_, maze_columns_);
  38.         fillMaze(in_stream);
  39.         initializeSolution();
  40.         // solution_[0][0] = '>';                                               //initializes starting position with '>' character
  41.         // backtrack_stack_.push(pos);
  42.         mazeIsReady();
  43.     }
  44.     in_stream.close();
  45. }
  46.  
  47. // destructor
  48. //post: deletes maze_ and solution_
  49. MazeSolver::~MazeSolver()
  50. {
  51.     if(maze_ready == false)                                                 //checks if maze was initialized
  52.     {
  53.         maze_ = nullptr;
  54.         solution_ = nullptr;
  55.     }
  56.     else
  57.     {
  58.         for(int i = 0; i < maze_rows_; i++)                                 //deletes maze_ character array
  59.         {
  60.             delete [] maze_[i];
  61.  
  62.         }
  63.         delete [] maze_;
  64.         maze_ = nullptr;
  65.         for(int j = 0; j < maze_rows_; j++)                                 //deletes solution_ character array
  66.         {
  67.             delete [] solution_[j];
  68.  
  69.         }
  70.         delete [] solution_;
  71.         solution_ = nullptr;
  72.     }
  73. }
  74.  
  75. bool MazeSolver::mazeIsReady()
  76. {
  77.     if((maze_rows_ > 0)&&(maze_columns_ > 0))                               //if maze_rows_ and maze_columns_ greater than 0, input file has been read
  78.     {
  79.         maze_ready = true;                                              //sets maze_ready as true
  80.         //returns true if mazeIsReady is called
  81.     }
  82.     else
  83.     {
  84.         maze_ready = false;                                             //if maze_rows_ and maze_columns unchanged, maze is not ready
  85.     }
  86.     return maze_ready;
  87. }
  88.  
  89. bool MazeSolver::solveMaze()
  90. {
  91.     Position curr_position;                                                 //instantiates curr_position of datatype curr_position
  92.     curr_position.row = 0;                                                  //initialize curr_position's row as 0
  93.     curr_position.column = 0;                                               //initialize curr_position's row as 0
  94.     bool solve = false;
  95.     // std::cout << "solving..." << std::endl;
  96.     backtrack_stack_.push(curr_position);
  97.     // backtrack_stack_.pop();
  98.     while(!backtrack_stack_.empty())
  99.     {
  100.         // std::cout << "in while" << std::endl;
  101.         if(solution_[(curr_position).row][(curr_position).column] == '$')   //if current position is '$', exit has been found
  102.         {
  103.             std::cout << "Found the exit!!!" << '\n';
  104.             std::cout << "The solution to this maze is:" << '\n';
  105.             printSolution();
  106.             solve = true;
  107.             break;
  108.         }
  109.         else if(extendPath(curr_position) == true)                          //checks curr_position for extending in South then East direction
  110.         {
  111.             solution_[(curr_position).row][(curr_position).column] = '>';
  112.             curr_position = backtrack_stack_.top();                             //current position = top of the stack
  113.         }
  114.         else
  115.         {
  116.             // std::cout << "else" << std::endl;
  117.             backtrack_stack_.pop();
  118.             maze_[curr_position.row][curr_position.column] = 'X';
  119.             solution_[curr_position.row][curr_position.column] = '@';
  120.             // std::cout << "end else" << std::endl;
  121.             if (backtrack_stack_.empty()){
  122.                 break;
  123.             }
  124.             curr_position = backtrack_stack_.top();                             //current position = top of the stack
  125.  
  126.         }
  127.     }
  128.     // std::cout << "done while" << std::endl;
  129.  
  130.     if(solve == false)
  131.     {
  132.         std::cout << "This maze has no solution." << '\n';
  133.         std::cout << "The solution to this maze is:" << '\n';
  134.         printSolution();
  135.     }
  136.     return solve;
  137. }
  138.  
  139. void MazeSolver::printSolution()
  140. {
  141.     for(int i = 0; i < maze_rows_; i++)                                     //for loop that moves through each row of array
  142.     {
  143.         for(int j = 0; j < maze_columns_; j++)                              //for loop that retrieves each column value for each row
  144.         {
  145.             std::cout << solution_[i][j] << " ";                            //outputs column value for each row then goes to next line, repeat
  146.         }
  147.         std::cout << "\n";
  148.     }
  149. }
  150.  
  151. void MazeSolver::initializeMaze(int rows, int columns)
  152. {
  153.     maze_ = new char *[rows];                                               //intitializes maze_ character array by allocating space
  154.     for(int i = 0; i < rows; i++)
  155.     {
  156.         maze_[i] = new char[columns];
  157.     }
  158. }
  159.  
  160. void MazeSolver::fillMaze(std::ifstream& input_stream)
  161. {                                                                           //fills position row by column
  162.     for(int i = 0; i < maze_rows_; i++)                                     //fills maze_ character array with values from input file using input_stream
  163.     {
  164.         for (int j = 0; j < maze_columns_; j++)
  165.         {
  166.             input_stream >> maze_[i][j];
  167.         }
  168.     }
  169. }
  170.  
  171. void MazeSolver::initializeSolution()
  172. {
  173.     solution_ = new char *[maze_rows_];                                      //initializes solution_array
  174.     for(int k = 0; k < maze_rows_; k++)
  175.     {
  176.         solution_[k] = new char[maze_columns_];
  177.     }
  178.     copyMazetoSolution();                                                    //fills array with characters from input file
  179. }
  180.  
  181. //copies position values from maze_ to solution_
  182. void  MazeSolver::copyMazetoSolution()
  183. {
  184.     for(int i = 0; i < maze_rows_; i++)
  185.     {
  186.         for(int j = 0; j < maze_columns_; j++)
  187.         {
  188.             solution_[i][j] = maze_[i][j];
  189.         }
  190.     }
  191. }
  192.  
  193. bool MazeSolver::extendPath(Position current_position)
  194. {
  195.     // std::cout << "extendPath" << std::endl;
  196.     bool extended = false;
  197.     if(isExtensible(current_position,SOUTH))                        //if SOUTH valid move, then try moving south, push current position onto stack
  198.     {
  199.         backtrack_stack_.push(getNewPosition(current_position, SOUTH));
  200.         extended = true;
  201.     }
  202.  
  203.     if(isExtensible(current_position,EAST))                         //if EAST, then try moving EAST. if move still valid, continue to try moving EAST, push current postion onto stack
  204.     {
  205.         backtrack_stack_.push(getNewPosition(current_position, EAST));
  206.         extended = true;
  207.     }
  208.     // std::cout << "end extendPath" << std::endl;
  209.  
  210.     return extended;
  211. }
  212.  
  213. Position MazeSolver::getNewPosition(Position old_position, direction dir)
  214. {
  215.     Position NewPosition;
  216.  
  217.     if(dir == SOUTH)
  218.     {
  219.         NewPosition.row = (old_position.row + 1);                           //if direction is SOUTH, y+1, x stays the same
  220.         NewPosition.column = old_position.column;
  221.     }
  222.     if(dir == EAST)
  223.     {
  224.         //if direction is EAST, y stays the same, x+1
  225.         NewPosition.column = (old_position.column + 1);
  226.         NewPosition.row = (old_position.row);                           //if direction is SOUTH, y+1, x stays the same
  227.     }
  228.     return NewPosition;
  229. }
  230.  
  231. bool MazeSolver::isExtensible(Position current_position, direction dir)
  232. {
  233.     bool extensible = false;
  234.  
  235.     if(dir == SOUTH)
  236.     {
  237.         if((current_position.row+1) < maze_rows_)
  238.         {
  239.             if(maze_[(current_position.row+1)][current_position.column] == '_')         //checks if direction is SOUTH, if the next character is '_', and if the next row value is within the maze
  240.             {
  241.                 extensible = true;
  242.             }
  243.             else if(maze_[(current_position.row+1)][current_position.column] == '$')        //checks if direction is SOUTH, if the next character is '$', and if the next row value is within the maze
  244.             {
  245.                 extensible = true;
  246.             }
  247.             else if(maze_[(current_position.row+1)][current_position.column] == 'X')      //checks if direction is SOUTH, if the next character is 'X', and if the next row value is within the maze
  248.             {
  249.                 extensible = false;
  250.             }
  251.             else if(maze_[(current_position.row+1)][current_position.column] == '*')        //checks if direction is SOUTH, if the next character is '*', and if the next row value is within the maze
  252.             {
  253.                 extensible = false;
  254.             }
  255.         }
  256.     }
  257.     if(dir == EAST)
  258.     {
  259.         if((current_position.column+1) < maze_columns_)
  260.         {
  261.             if(maze_[current_position.row][(current_position.column+1)] == '_')         //checks if direction is SOUTH, if the next character is '_', and if the next row value is within the maze
  262.             {
  263.                 extensible = true;
  264.             }
  265.             else if(maze_[current_position.row][(current_position.column+1)] == '$')        //checks if direction is SOUTH, if the next character is '$', and if the next row value is within the maze
  266.             {
  267.                 extensible = true;
  268.             }
  269.             else if(maze_[current_position.row][(current_position.column+1)] == 'X')        //checks if direction is SOUTH, if the next character is 'X', and if the next row value is within the maze
  270.             {
  271.                 extensible = false;
  272.             }
  273.             else if(maze_[current_position.row][(current_position.column+1)] == '*')        //checks if direction is SOUTH, if the next character is '*', and if the next row value is within the maze
  274.             {
  275.                 extensible = false;
  276.             }
  277.         }
  278.     }
  279.     return extensible;
  280. }
  281.  
  282.  
  283. int main() {
  284.     MazeSolver solver("input5.txt");
  285.     if(solver.mazeIsReady())
  286.     {
  287.         solver.solveMaze();
  288.         solver.printSolution();
  289.     }
  290.     return 0;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement