I want to make a program to find if a path exists from upper right corner to down left corner in a maze via backtracking. The input numbers are n and m which are the dimensions of rectangular maze and a maze, character '.' means a tile which you can go through and character 'x' means a tile which you cant go through. I have wrote the code, its fairly simple but nothing gets displayed whilst it should display "da" (on Serbian "yes") and "ne" (on Serbian "no").
#include <bits/stdc++.h>
using namespace std;
bool maze[20][20]; //defined maze of maximum size 20x20
//checking if a position is viable for moving through
bool Safe(int n, int m, int x, int y)
{
if(x >= 0 && x < n && y >= 0 && y < m)
{
if(maze[x][y] == 1) return true;
}
return false;
}
bool Utility(int n, int m, int x, int y) //main utility function
{
if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
{
return true;
}
if(Safe(n, m, x, y))
{
if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
{
if(Utility(n, m, x + 1, y))
{
return true;
}
}
if(Safe(n, m, x, y + 1))
{
if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
{
return true;
}
}
if(Safe(n, m, x - 1, y))
{
if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
{
return true;
}
}
if(Safe(n, m, x, y - 1))
{
if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
{
return true;
}
}
}
return false; // returning false
}
int main()
{
int n, m;
cin >> n >> m; // input dimensions of the maze
for(int i = 0; i < n; i++) // input maze
{
for(int j = 0; j < m; j++)
{
char c;
cin >> c;
if(c == '.') //character '.' means a tile which you can go through
{
maze[i][j] = 1;
}
else //character 'x' means a tile which you cannot go through
{
maze[i][j] = 0;
}
}
}
if(Utility(n, m, 0, 0)) //printing yes or no
{
cout << "da";
}
else
{
cout << "ne";
}
return 0;
}
Sample Input:
8 8
.x.....x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
.x.x.x.x
...x.x..
Sample output: da
The problem was that, say if you go from (0, 0) -> (1, 0), then at (1, 0) you can again go back to (0, 0) and this would loop forever. To avoid that, I created a visited array which will have value true if cell (x, y) is already visited, else false.
I have marked where I made the changes with ///////////// change here ///////////// comment
#include <bits/stdc++.h>
using namespace std;
bool maze[20][20]; //defined maze of maximum size 20x20
///////////// change here /////////////
bool visited[20][20];
bool Safe(int n, int m, int x, int y) //checking if a position is viable for moving through
{
if(x >= 0 && x < n && y >= 0 && y < m)
{
if(maze[x][y] == 1) return true;
}
return false;
}
bool Utility(int n, int m, int x, int y) //main utility function
{
if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
{
return true;
}
///////////// change here /////////////
if(!visited[x][y] && Safe(n, m, x, y))
{
///////////// change here /////////////
visited[x][y] = true;
if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
{
if(Utility(n, m, x + 1, y))
{
return true;
}
}
if(Safe(n, m, x, y + 1))
{
if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
{
return true;
}
}
if(Safe(n, m, x - 1, y))
{
if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
{
return true;
}
}
if(Safe(n, m, x, y - 1))
{
if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
{
return true;
}
}
}
return false; // returning false
}
int main()
{
int n, m;
cin >> n >> m; // input dimensions of the maze
for(int i = 0; i < n; i++) // input maze
{
for(int j = 0; j < m; j++)
{
char c;
cin >> c;
if(c == '.') //character '.' means a tile which you can go through
{
maze[i][j] = true;
}
else //character 'x' means a tile which you cannot go through
{
maze[i][j] = false;
}
///////////// change here /////////////
visited[i][j] = false;
}
}
if(Utility(n, m, 0, 0)) //printing yes or no
{
cout << "da";
}
else
{
cout << "ne";
}
return 0;
}
Here's the link where I tested it: https://ideone.com/vVqAjF
Related
I know my code is extremely close I have all of my functions working except the moveKnight() function if you do not know what knights Tour is, it's a program we are writing to help learn recursion in class. The knight is suppose to touch every space on the 8*8 chessboard only once and then prints out the move number that it took to get there. It currently only prints out the first position board[0][0]=1
but does not give "No solution".
I can not figure out where I should start looking for the problem any help is greatly appreciated.
#include <iostream>
using namespace std;
//Global Variables
//Defining the 8 possible Moves in the order from class
int yMove[8] = { 1,2, 2, 1,-1,-2,-2,-1 };
int xMove[8] = { 2,1,-1,-2,-2,-1, 1, 2 };
int board[8][8];
int startx, starty = 0;
int movecount = 1;
//checks if move is safe
bool checkSafe(int x, int y)
{
return (x >= 0 && x < 8 && y >= 0 && y < 8 && board[x][y] == 0);
}
//Prints Current board
void printBoard(int board[8][8])
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
cout << " " << board[x][y] << " ";
cout << endl;
}
}
bool moveKnight(int x, int y, int movecount)
{
if (!checkSafe(x, y))
{
board[x][y] = movecount;
return true;
}
//end condition
if (movecount == 64)
return true;
if (moveKnight(x + xMove[1], y + yMove[1], movecount + 1))
return true;
else if (moveKnight(x + xMove[0], y + yMove[0], movecount + 1))
return true;
else if (moveKnight(x + xMove[2], y + yMove[2], movecount + 1))
return true;
else if (moveKnight(x + xMove[3], y + yMove[3], movecount + 1))
return true;
else if (moveKnight(x + xMove[4], y + yMove[4], movecount + 1))
return true;
else if (moveKnight(x + xMove[5], y + yMove[5], movecount + 1))
return true;
else if (moveKnight(x + xMove[6], y + yMove[6], movecount + 1))
return true;
else if (moveKnight(x + xMove[7], y + yMove[7], movecount + 1))
return true;
else
{
board[x][y] = 0;
return false;
}
}
int KnightTour()
{
//creating board
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
board[x][y] = 0;
}
board[startx][starty] = 1;
movecount + 1;
//No possible moves
if (!moveKnight(startx, starty, movecount))
cout << "Not possible";
else
{
//yes possible now print
printBoard(board);
}
//exits
return 0;
}
int main()
{
//calls knights tour
KnightTour();
cout << endl;
system("pause");
return 0;
}
Your moveKnight function returns immediately because it determines the very first position is not a valid move. The reason is you initialized the board with a non-zero value at the start position.
Remove these two lines from main:
board[startx][starty] = 1;
movecount + 1;
The first one breaks your recursion, and the second one does nothing at all.
Additionally, the logic after calling checkSafe() is screwy, because at the moment when you determine a move is either out-of-bounds or already-played, you are writing a value to the board. That's going to result in undefined behavior.
Correcting these things, and also simplifying the recursive calls:
bool moveKnight(int x, int y, int movecount)
{
if (checkSafe(x, y))
{
board[x][y] = movecount;
if (movecount == 64)
return true;
for (int i = 0; i < 8; i++)
{
if (moveKnight(x + xMove[i], y + yMove[i], movecount + 1))
return true;
}
board[x][y] = 0;
}
return false;
}
The problem
I'm new to this sort of programming, and my C++ maze solver is stuck in a loop.
The maze is a simple char 2-D matrix with an asterisk (*) for a valid path square, and a slash (/) for a wall square.
Why doesn't the program stop when it finds a '/'?
# include < iostream >
using namespace std;
char lab[6][6] =
{ { '/','/','/','/','/' },
{ '/','*','/','/','/' },
{ '/','*','*','*','/' },
{ '/','/','*','/','/' },
{ '/','/','*','/','/' },
{ '/','/','*','*','*' } };
int x, y;
void run(char lab[][6], int, int);
bool movU() // Move Up
{
if (lab[x][y - 1] == '*')
return true;
else
return false;
}
bool movR() // Move right
{
if (lab[x + 1][y] == '*')
return true;
else
return false;
}
bool movD() // Move Down
{
if (lab[x][y + 1] == '*')
return true;
else
return false;
}
bool movL() // Move Left
{
if (lab[x - 1][y] == '*')
return true;
else
return false;
}
void run(char lab[][6], int x, int y)
{
if (movU() == true) // I'm getting stuck right here
run(lab, x, y - 1); // Getting negative numbers here
else if (movR() == true)
run(lab, x + 1, y);
else if (movD() == true)
run(lab, x, y + 1);
else if (movL() == true)
run(lab, x - 1, y);
else
cout << "Error" << endl;
}
int main()
{
x = 1, y = 2; // Start position
run(lab, x, y);
return 0;
}
Besides the global scoping problem with x and y, you haven't done anything to keep the subscripts from running over the edge of the maze into random memory locations. As a result, y continues to decrement, and you back up through memory looking for an asterisk. Since you also recur, you continue this until you blow all your stack space.
Also, you don't seem to be comfortable with boolean values yet: you do a lot of extra work to deal with constants true and false, rather than simply using the value of a boolean expression.
I've fixed these items in your code:
# include <iostream>
using namespace std;
char lab[6][6] =
{
{ '/','/','/','/','/' },
{ '/','*','/','/','/' },
{ '/','*','*','*','/' },
{ '/','/','*','/','/' },
{ '/','/','*','/','/' },
{ '/','/','*','*','*' }
};
void run(char lab[][6], int, int);
bool movU(int x, int y) // Move Up
{
return x >= 0 && y >= 1 &&
x < 6 && y < 6 &&
lab[x][y - 1] == '*';
}
bool movR(int x, int y) // Move right
{
return x >= 0 && y >= 0 &&
x < 5 && y < 6 &&
lab[x+1][y] == '*';
}
bool movD(int x, int y) // Move Down
{
return x >= 0 && y >= 0 &&
x < 6 && y < 5 &&
lab[x][y + 1] == '*';
}
bool movL(int x, int y) // Move Left
{
return x >= 1 && y >= 0 &&
x < 6 && y < 6 &&
lab[x-1][y] == '*';
}
void run(char lab[][6], int x, int y)
{
cout << "ENTER run; x = " << x << "\ty = " << y << endl;
if (movU(x, y)) // I'm getting stuck right here
run(lab, x, y - 1); // Getting negative numbers here
else if (movR(x, y))
run(lab, x + 1, y);
else if (movD(x, y))
run(lab, x, y + 1);
else if (movL(x, y))
run(lab, x - 1, y);
else
cout << "Error" << endl;
}
int main()
{
// x = 1, y = 2; // Start position
run(lab, 1, 2);
return 0;
}
This stays within bounds ... and loops until it runs out of stack space. You need to add code to avoid rechecking ground you've already visited. For instance, you can mark the location with another character, such as an underscore.
You also need to recognize when you're done. What marks the maze exit? You'll need a check in your run routine for that.
I'm having trouble with the alpha-beta pruning algorithm from Wikipedia:
function alphabeta(node, depth, α, β, Player)
if depth = 0 or node is a terminal node
return the heuristic value of node
if Player = MaxPlayer
for each child of node
α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Beta cut-off *)
return α
else
for each child of node
β := min(β, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Alpha cut-off *)
return β
Specifically the recursive call of alpha-beta. I keep getting a SegFault error on the first pass of alpha-beta.
Here is my alpha-beta function:
int alphabeta(int board[9], int depth, int alpha, int beta, bool max_player) {
int score = 0;
max_player = true;
if(depth == 0){
return score;
}
if(max_player) {
alpha = INT_MIN;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player); <--- where error originates
alpha = MAX(alpha, score );
if (beta <= alpha) break;
}
return alpha;
}
else {
beta = INT_MAX;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
beta = MIN(beta, score );
if (beta <= alpha) break;
}
return beta;
}
}
with the overall implementation here:
# include "stdio.h"
# include "limits.h"
int MAX (int x, int y) {
if (x > y) {
return x;
}
else {
return y;
}
}
int MIN (int x, int y) {
if (x < y) {
return x;
}
else {
return y;
}
}
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int alphabeta(int board[9], int depth, int alpha, int beta, bool max_player) {
int score = 0;
max_player = true;
if(depth == 0){
return score;
}
if(max_player) {
alpha = INT_MIN;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
alpha = MAX(alpha, score );
if (beta <= alpha) break;
}
return alpha;
}
else {
beta = INT_MAX;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
beta = MIN(beta, score );
if (beta <= alpha) break;
}
return beta;
}
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -alphabeta(board[9],6, -10000, 10000, true);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
I'm thinking that my implementation is not correctly identifying the "child nodes" of the current board, but I am lost as to how to code that with regard to an array of integers. Any advice would be greatly appreciated.
One error is here (and you are making similar mistakes in other places in your code):
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
The first parameter, board[9] is accessing an out-of-bounds element of the board array. You're sending a single int, namely board[9], but board[9] is an element that is out-of-bounds of board, thus you're invoking undefined behavior.
I don't know what your intentions are with the code above, but if you are trying to pass the buffer pointed to by board:
score = alphabeta(board, depth - 1, alpha, beta, !max_player);
If you're trying to pass the last element of the board:
score = alphabeta(board[8], depth - 1, alpha, beta, !max_player);
In addition, if you're not aware, function prototypes like this:
int win(const int board[9])
are no different than this:
int win(const int* board)
Arrays decay to pointers -- you are not actually passing an array.
The example here shows what the program would look like when corrected (the runtime error is due to missing input).
You also have some very suspicious code, for example:
while (move >= 9 || move < 0 && board[move] == 0);
If move < 0, you are accessing board with a negative index, which is another out-of-bounds access.
I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.
I am trying to traverse a maze and produce all valid paths. The maze always starts at S. All exits could be anywhere along the right-most
wall. The top wall and bottom walls are always solid rows of # symbols. I can only move through and adjacent square that contains a char that is not "#".
This is an example of a maze.
######
Sa#hln
#bdp##
##e#ko
#gfij#
######
This is what should be printed out:
S,a,b,d,e,f,i,j,k,o
S,a,b,d,p,h,l,n
But I get S,a,b,d,e,f,i,j,k,o,p,h,l,n
This is the first path, and the half of the second path where it forked. I would be grateful for any help. Thank you.
#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
if (maze[r][c] == "#"){
return false;
}
return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
if (maze[r][c] == false){
return true;
}
return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
if (r - 1 < 0 || r + 1 > 6 ||
c - 1 < 0 || c + 1 > 6){
return false;
}
return true;
}`
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
return true;
}
return false;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
int y = rows;
int x = columns;
string path = maze[y][x];
stack<string> s;
if (thereIsNextMove(maze, bmaze, y, x) || x == 5){
s.push(path);
cout << s.top();
s.pop();
}
if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y - 1, x);
}
if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y + 1, x);
}
if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x - 1);
}
if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x + 1);
}
}
int main(){
while (getline(in, str))
{
file_contents += str;
//file_contents.push_back('\n');
}
string maze[6][6];
for (int row = 0; row < 6; row++){
for (int col = 0; col < 6; col++){
char mazeChar = file_contents.at(6 * row + col);
maze[row][col] = mazeChar;
}
}
bool bmaze[6][6];
for (int brow = 0; brow < 6; brow++){
for (int bcol = 0; bcol < 6; bcol++){
bmaze[brow][bcol] = false;
}
}
string path;
generate_all_paths(maze, bmaze, 1, 0);
int age;
cin >> age;
return 0;
}
Here the stack inside 'generate_all_paths' function has not been used at all. In the given implementation that stack contains at most one element at any given time. Instead of printing the path every time you find one, just keep the stack global and push the new path to it then print the entire stack at once when you reach the destination then just remove the element from the stack at the end of the function, like how you would walk back to the fork point, if you are actually traversing the maze.
#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
stack<string> s;
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
if (maze[r][c] == "#"){
return false;
}
return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
if (maze[r][c] == false){
return true;
}
return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
if (r - 1 < 0 || r + 1 > 6 ||
c - 1 < 0 || c + 1 > 6){
return false;
}
return true;
}
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
return true;
}
return false;
}
template < typename T > void print( const std::stack<T>& stk )
{
struct cheat : std::stack<T> { using std::stack<T>::c ; } ;
const auto& seq = static_cast< const cheat& >(stk).c ;
for( const auto& v : seq ) std::cout << v << ' ' ;
std::cout << '\n' ;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
int y = rows;
int x = columns;
string path = maze[y][x];
bool pushed = false;
if (thereIsNextMove(maze, bmaze, y, x)){
s.push(path);
pushed = true;
}
if (x == 5){
s.push(path);
pushed=true;
print(s);//printing the entire stack once a path has been found
}
if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y - 1, x);
}
if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y + 1, x);
}
if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x - 1);
}
if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
bmaze[y][x] = true;
generate_all_paths(maze, bmaze, y, x + 1);
}
if(pushed){
s.pop();//removing the element from the stack like how you walk back to fork point
}
}
int main(){
while (getline(in, str))
{
file_contents += str;
//file_contents.push_back('\n');
}
string maze[6][6];
for (int row = 0; row < 6; row++){
for (int col = 0; col < 6; col++){
char mazeChar = file_contents.at(6 * row + col);
maze[row][col] = mazeChar;
}
}
bool bmaze[6][6];
for (int brow = 0; brow < 6; brow++){
for (int bcol = 0; bcol < 6; bcol++){
bmaze[brow][bcol] = false;
}
}
string path;
generate_all_paths(maze, bmaze, 1, 0);
int age;
cin >> age;
return 0;
}
PS - I had added a function named print just to print the stack