I've written a simple recursive maze solving problem that uses recursion to find the least number of moves to solve. However, at dead ends, the program has trouble backing up the traced path.
To try to solve the problem, I started to write inverse functions of the move functions. They could be used to reverse the path, but would still need some way to identify which one to use.
//Read in maze
ifstream mazeFile;
mazeFile.open("MazeSample.txt");
vector<string> mazeRead{ istream_iterator<string>(mazeFile), istream_iterator<string>() };
maze = mazeRead;
//Move checks
vector<string> maze;
int numMoves;
int leastMoves = 1000;
int row;
int column;
bool canMoveUp(int row, int column) {
try {
if (maze.at(row - 1).at(column) != ('O')) {
cout << "(Can't move up)" << endl;
if (maze.at(row - 1).at(column) == 'E') {
return true;
}
return false;
}
}
catch (const out_of_range& error) {
cout << "(Can't move up)" << endl;
return false;
}
return true;
}
bool canMoveDown(int row, int column) {
try {
if (maze.at(row + 1).at(column) != ('O')) {
cout << "(Can't move down)" << endl;
if (maze.at(row + 1).at(column) == 'E') {
return true;
}
return false;
}
}
catch (const out_of_range& error) {
cout << "(Can't move down)" << endl;
return false;
}
return true;
}
bool canMoveLeft(int row, int column) {
try {
if (maze.at(row).at(column - 1) != ('O')) {
cout << "(Can't move left)" << endl;
if (maze.at(row).at(column - 1) == 'E') {
return true;
}
return false;
}
}
catch (const out_of_range& error) {
cout << "(Can't move left)" << endl;
return false;
}
return true;
}
bool canMoveRight(int row, int column) {
try {
if (maze.at(row).at(column + 1) != ('O')) {
cout << "(Can't move right)" << endl;
if (maze.at(row).at(column + 1) == 'E') {
return true;
}
return false;
}
}
catch (const out_of_range& error) {
cout << "(Can't move right)" << endl;
}
return true;
}
//Maze solve function
void solve(int row, int column) {
numMoves = numMoves + 1; //count moves
//Base case (solution found; current position is 'E')
if (maze[row][column] == 'E') {
if (numMoves < leastMoves) {
leastMoves = numMoves;
}
}
if (maze[row][column] != 'E') {
maze[row][column] = 't'; //mark path
}
// move up and see if move leads to solution (recursively)
if (canMoveUp(row, column)) {
cout << "(Move up)" << endl;
row = row - 1;
column = column;
solve(row, column);
}
// if move chosen above doesn't lead to solution, move down & check
if (canMoveDown(row, column)) {
cout << "(Move down)" << endl;
row = row + 1;
column = column;
solve(row, column);
}
// if move chosen above doesn't lead to solution, move left & check
if (canMoveLeft(row, column)) {
cout << "(Move left)" << endl;
row = row;
column = column - 1;
solve(row, column);
}
// if move chosen above doesn't lead to solution, move right & check
if (canMoveRight(row, column)) {
cout << "(Move right)" << endl;
row = row;
column = column + 1;
solve(row, column);
}
// if no above solution works, then unmark cell
//backtrack (keeps going until all solutions reached)
maze[row][column] = 'O';
cout << "Mark as 'O'";
numMoves = numMoves - 1;
//TODO: PROBLEM: ROW/COLUMN NOT RESET AFTER STUCK; KEEPS SAME VALUE
//Questionable code
if (!canMoveUp(row, column)) {
//Inverse of canMove?
row = row + 1;
column = column;
}
//Display vector contents
cout << endl;
for (int row = 0; row < maze.size(); row++) {
cout << endl;
for (int column = 0; column < maze[row].size(); column++) {
cout << maze[row][column];
}
}
cout << endl;
}
When hitting a dead end, I expected the maze to back up to the last junction with movement options. Instead, the cursor goes back and forth, failing to solve. This is likely due to the implementation of the move functions; if able to move, it sets the row/column variables to the new space.
Upon not being able to move in any of the four directions, I'd expect the code to undo the previous movement(s) until reaching the last junction.
Aucun commentaire:
Enregistrer un commentaire