Recursive Mazes: when multiple paths - c++

Following is a representation of a maze that I wish to solve using recursion. S is the starting point and F is the finishing point. The numbers on top and left represent the coordinates.
I have written the code but the problem is that when the current position is 3,2 then there are 3 options for next current position: top, left and down.
If I remove the option to go leftward, then it is solved correctly and the output is "Maze not solved" because current positive never reaches F(finishing coordinate).
However, with leftward condition, I get no solution and an infinite loop is run.
Here's part of the code (only including direction==3 which means if next move will be leftward):
bool solveRecursive(char grid[][6],int siz, int curRow, int curCol, int direction,bool check)
{
while(check==0)
{
if(curRow==4 && curCol==0)
{
check = 1;
}
else if (direction == 3) // If open space in west
{
//}
if(grid[curRow][curCol-1] == '.')
{
curCol--;
check = solveRecursive(grid,siz,curRow,curCol,3,check);
}
if (grid[curRow-1][curCol] == '.')
{
curRow--;
check = solveRecursive(grid,siz,curRow,curCol, 0,check);
}
else if (grid[curRow+1][curCol] == '.')
{
curRow++;
check = solveRecursive(grid,siz,curRow, curCol, 2,check);
}
else
return 0;
}
}
return check;
}

Related

Calling functions randomly using a vector

#assume everything needed is included
void Robot::moveRobot()
{
//calls a random directon for robot to move in
//if direction returns false (not able to move in that direction),
//call another random direction up to 4 times, excluding the one(s)
//already called. If they all return false, do not move the robot.
//vecDir = {moveForward(), moveBackward(), moveRight(), moveLeft()}
// = {0,1,2,3} initially
vector<int> vecDir{0,1,2,3}; //vetor indicating direction to move
int num = rand() % vecDir.size();
if(num == vecDir[0])
{
//if not able to move forward, try a different random direction
if(Robot::moveForward() == false)
{
vecDir.erase(num);
//here, vector will be vecDir={1,2,3}
}
}
else if(num == vecDir[1])
{
Robot::moveBackward();
}
else if(num == vecDir[2])
{
Robot::moveRight();
}
else //num == vecDir[3]
{
Robot::moveLeft();
}
}
Hi! I'm trying to randomly call these four functions within the moveRobot() function using a vector whose size is changed depending on if a direction cannot be called. I set moveForward() to the first element, moveBackward() to the second element, etc. If any of the moveXXXX() functions are false, I want to delete that element of the array. Example code shown
Example output:
//before doing anything, vecDir = {0,1,2,3}
int num = rand() % vecDir.size(); //assume num = 1, so it calls moveBackward()
//assume moveBackward() is false, so gets rid of that element
vecDir.erase(num); //new vecDir = {0,2,3};
// vecDir(0) would be moveForward(), vecDir(1) is now moveRight(), vecDir(1) is now moveLeft()
How would I continue this process to exhaust all elements and not move a robot? I know a for loop would be involved, but I cannot think of where to use it. I am also not sure if my thinking is correct by using if else for each element. Any help is appreciated, and I apologize if the question is confusing. I can clear it up if there are any misunderstandings.
Just have a vector of function pointers, rather then numbers.
void Robot::moveRobot() {
// vector of pointers to functions to move
std::vector<bool()> moves{
moveForward(), moveBackward(), moveRight(), moveLeft()
};
// we repeat the process until any moves are available.
while (moves.size() > 0) {
// pick a random move
const int num = rand() % moves.size();
// try to move
if (moves[num]() == true) {
// yay, we moved!
break;
}
// we did not move - remove current option and repeat
moves.erase(moves.begin() + num);
}
}

Determine the current output to the speaker C++ Beginner

Recently, I've began learning C++ in college and was asked to make a looping sequence of "*" with the sequence going like this:
*
***
*****
*******
*********
*********
*******
*****
***
*
[continues indefinitely until it goes x lines, where x is specified at the start]
How I did it if you need a visualisation:
#include<iostream>
#include<windows.h>
using namespace std;
int main() {
int hFar=0; //Variable that will be used to find out how many parts into the sequence the user would like to travel.
unsigned long int fibSequenceA = 0; //Unsigned doesn't overflow as easilly. This is the first value of the fibunacci sequence, it's defined as 0 to start.
unsigned long int fibSequenceB = 1; // Second Value of fibbunacci sequence. Defined at 1 to start.
int sPart = 1;//Used for the * sequence, it is the part of the sequence that the loop is on. It changes dynamically by either +2 or -2 every loop.
int cValue = 0;// also for the * sequence, it is the current number of * typed.
int sDirection = 0; // used to change from subtracting 2, and adding 2.
int redo = 1; // used to ensure that every 9 and every 1 the sequence repeats that number a second time. Starts at one because the sequence starts with only 1 single * rather then 2 *.
cout << "How far into the second sequence would you like to travel?" << endl; //Requests how far into the * sequence you'd like to go.
cin >> hFar; //inputs answer into variable.
for(int i = 0; i < hFar; i++ ) {//begins for statement. Notice there's no hfar/2. There will only be 1 output per line now.
while(cValue < sPart) { //Basic while loop to input the ammount of * on the current line. Works by adding a * depending on what part of the sequence it is.
cout << "*"; //self explainitory.
cValue++; //raises the cValue in order to keep track of the current number of *. Also prevents infinite loop.
}
if(sPart == 9 && redo == 0) { //Checks if the sequence part is 9, meaning that the value begins to reduce to 1 again. But first, it must repeat 9 to keep with the sequence.
sDirection = 3; //sets the direction to 3 to make sure that the value of sPart stays at 9, instead of reducing by 2.
redo = 1; //resets the redo.
cValue = 8; //changes the value of the current number of 8. Not sure if this is important, It gets done again later to make sure anyway.
sPart = 9; //Changes the sPart to 9, the needed number of *. Also redone later, but to make sure, I kept this here.
}
else if(sPart == 9 && redo == 1) { // if the sequence has already redone the 9th *
sDirection = 1; //sets the direction to 1; The sequence will reverse.
redo = 0; //returns redo to 0 to ensure that next time it reaches 1, it repeats the 1 * again.
}
else if(sPart == 1 && redo == 0) { //when the value reaches one for the second time, it needs to repeat that value.
sDirection = 3; //sets the direction to 3 again to stop the change.
redo = 1; //resets the redo.
cValue = 0;//also might be redundant.
}
else if(sPart == 1 && redo == 1) { // stops the duplicate number of *
sDirection = 0; //sets the direction to +2 again.
redo = 0;//resets the redo.
}
Sleep(50);
cout << endl; //adds a new line. This ensures that we get a new line after every part rather then 900 * on one line.
if(sDirection == 0) { //if the direction is positive.
sPart += 2; //adds 2 to the spart to keep with the sequence.
cValue = 0; //resets the cValue to 0 so the while statement works again.
}
else if(sDirection == 1) { //if the direction is negative
sPart -=2; //subtracts 2 from the spart to keep with the sequence.
cValue = 0; //resets the cValue to keep the while statement working.
}
else if(sDirection = 3) { //if the change is
//Could have been done differently. Could have just set the values to themselves, but it wasn't working. not sure why.
if(sPart == 9){ //if the spart is currently 9.
sPart = 9; //keeps it at 9.
cValue = 0; //resets the cValue.
}
else if(sPart == 1){ //if the spart is currently 1
sPart = 1; //keeps it at one.
cValue = 0; //resets the cValue.
}
}
}
return 1;//ends the code.
}
[Sorry about all the comments, I'm trying to make sure I understand what I'm doing, like I said, I'm learning :)]
While fooling around with the loops, I ended up putting the Sleep() function in, so that it produced a wave effect when generating the sequence. This got me thinking, and I wanted to know if it would be possible to make the command prompt act like a makeshift volume visualizer. (The more "*" the higher the volume at that point in time).
So, when playing a song on my computer, the program would find the total output to the speaker, and put a number of "*" that correlate to that volume, and would continue this until the program ends, producing (hopefully) an interesting effect. (if you're confused, play a song on your computer, right click on the speaker icon on the task bar, and click open volume mixer, and look at the volume levels change, this is the type of effect that I'm looking for)
Would this be possible? I've been googling the issue, (found things like This and I've found a number of ways to find out the current MASTER volume, and change that, But I'm looking for more of the actual volume that one hears, not the maximum volume that my speakers can output.
Here's somewhat of what I'm looking to do.
int sPart = x; //x = the current output of the speaker
int cValue = 0 //the current number of "*" output
while([somecondition I'm not sure when i want the sequence to stop yet]) {
while(cValue < sPart) {
cout << "*";
cValue++;
}
cout << endl; //ends the current line, making room for the next value of the volume.
Sleep(50); //waits 50ms before finding the next volume value.
sPart = [current speaker value]; //finds the value of the speaker again.
cValue = 0; //resetting the number of "*" back to zero.
}
//I just reused the variables from my original code.
Would this be possible? If so, would a beginner be capable of this? Again, If so, how would it be done?

Finding path in a 2-d maze

Why is this code giving run-time error. I am trying to find if their exist a path inside the maze to reach the food(2). 0 representing obstacle, 1 representing path, and 2 is for the destination.
`{0,1,1,0,0},
{1,0,1,1,1},
{0,0,0,0,0},
{0,1,1,1,1},
{0,0,1,1,0},
{1,0,1,1,2}`
I'm passing the starting point as findpath(a,3,2) where a is the maze and i=3, j=2 as the starting point.
Code on ideone: http://ideone.com/poF9um
Thanks guys, for helping me. I have rectified my mistake.
Here's the ideone link for the updated code: http://ideone.com/poF9um
Thanks.
#include <iostream>
using namespace std;
/*int insideMaze(int x, int y){
if(x>=6 || y >=5 || x<0 || y< 0)
{
return 0;
}
return 1;
}*/
bool findPath(int a[6][5], int n1, int m1){
if(n1>=6 || m1 >=5 || n1<0 || m1<0){
return false;
}
if(a[n1][m1] == 0){
return false;
}
if(a[n1][m1]==2){
return true;
}
//a[n1][m1] = 4;
if(findPath(a,n1-1,m1)==true){
return true;
}
if(findPath(a,n1,m1-1)==true){
return true;
}
if(findPath(a,n1+1,m1)==true){
return true;
}
if(findPath(a,n1,m1+1)==true){
return true;
}
return false;
}
int main() {
// your code goes here
//int a[10][10];
int a[6][5] = {
{0,1,1,0,0},
{1,0,1,1,1},
{0,0,0,0,0},
{0,1,1,1,1},
{0,0,1,1,0},
{1,0,1,1,2}
};
if(findPath(a,3,2)){
cout<<"Path Found";
}
return 0;
}
The problem is caused by stack overflow. Your depth-first search does not mark locations that it visits, so the same location would be visited multiple times.
You start at (3, 2), and try going left.
This takes you to (3, 1).
There is no path left of (3, 1), so you go right.
This takes you back to (3, 2), from where you try to go left.
This takes you to (3, 1).
There is no path left of (3, 1), so you go right...
See the problem? To fix it, add another array of the spots that you have visited, and check it before continuing with the search. This will fix the issue.
I guess that the code causes infinite recursive calls.
You begin with executing findPath(a,3,2).
Since a[3][2]==1, the code will call findPath(a,3,1).
Now, since a[3][1]==1, the code will later call again to findPath(a,3,2) again...
And so on... Until you run out of memory / stack overflow...

Cellular automaton doesn't make new cells

I'm trying to make a program that is able to create every kind of cellular automatons, such as Conway's game of life and everything else too.
The graphic implementation works perfectly already, so I wouldn't waste your time with that (especially that it uses Allegro libraries), but the functions that counts the cells, doesn't work properly.
That's what I have at the moment. (the code is in order, I just break it with commentary to make everything clear for you)
Pre-definitions:
#define fldwidth 110
#define fldheight 140
A structure for graphics:
typedef struct tiles
{
unsigned char red, green, blue;
}tiles;
Two predefined structures: the RGB code of an alive and a dead test cell.
const tiles TEST_ALIVE = {200,0,0};
const tiles TEST_DEAD = {100,0,0};
A function that checks the color equality of a structure variable and a constant structure.
bool equality(tiles& a, const tiles& b)
{
if (a.red == b.red && a.green == b.green && a.blue == b.blue)
{
return true;
} else {
return false;
}
}
The main function. It gets two arrays of structures (first one is the current round, second one is where counting happens; in round loop, after the counting, b array will be copied into a array); when started, it does the following steps for every structures: counts, how many living cells it has in its neighborhood (if its a living cell, it starts from -1 to avoid counting itself as neighbours, otherwise it start from 0 regularly), then if itself is NOT a living test cell (but anything else) and has 5 neighbours, it becomes a living test cell; if itself is a living test cell and has 2 neighbours, it becomes a dead cell.
void Test(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(arra[i][j], TEST_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<j+1;b++)
{
for (a=i-1;a<i+1;a++)
{
if (equality(arra[a][b], TEST_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
{
arrb[i][j] = TEST_ALIVE;
}
if (equality(arra[i][j], TEST_ALIVE) == true && counter == 2)
{
arrb[i][j] = TEST_DEAD;
}
}
}
}
The problem is that when the counting begins, every living cell becomes dead immediately in the first round and sometimes they just disappear, even without becoming dead cell (which is a darker red colour obviously), and it happens for almost every "counter == XY" check.
I've already got some tips, but I have no idea, why it doesn't work. Does it have logic failure? Because I can't see the mistake, even though it is there.
EDIT:
arra[fldwidth][fldheight]
is replaced by
arra[i][j]
and
arrb[i][j] = arra[i][j];
is added. Now everything stays as they were put.
Why do you access arra[fldwidth][fldheight] for the equality checks? This is outside of the array, one element behind the last element in the array! What you want to access is arra[i][j].
And unless arrb starts as a copy of arra, you probably want to add arrb[i][j] = arra[i][j]; in front of the two equality checks. That way if a cell doesn't meet any of the two state change rules, it will keep its current state.
Edit:
You also need to let the loop run between i-1 and i+1, so it should be: for (a = i-1; a <= i+1; a++), same for b!
I think your bug is in the line:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == false && counter == 5)
This should be:
if (equality(arra[i][j], TEST_ALIVE) == false && counter == 5)
and similarly for the line:
if (equality(arra[fldwidth][fldheight], TEST_ALIVE) == true && counter == 2)

write trie parsing recursive function with node step over

The purpose: This function parses through a string trie following the path that matches an input string of characters. When all the char in the string are parsed, true is returned. I want to step over a char and return if there is still a valid path.
The application: the strings are a location hierarchy for a highway project. So, project 5 has an alignment C, that has an offset of N and a workzone 3; 5CN3. But, sometimes I want to define a string for all child locations for a project task that covers all the locations. So, '0' is all locations; for a half day operation like grade dirt has no workzones - all the so to represent this task is all workzones in the north alignment C; 5CN0. same for if an operation covers the whole project; 5000.
Approaches: I could have used a wildcard '?' function but I want to keep this specific step over for the purpose of abstracting the locations. Maybe '?' is the right approach, but seems to loose some control. Also, this could be written without the for loop and use a position index parameter; maybe that is where this goes wrong - maybe on backtracking.
Code: nodeT is the trie nodes, word is the input string, this function is a bool and returns 1/0 if the string path exists.
bool Lexicon::containsWordHelper(nodeT *w, string word)) //check if prefix can be combined
{
if(word == "") { //base case: all char found
return true;
} else {
for(int i = 0; i < w->alpha.size(); i++) { //Loop through all of the children of the current node
if (w->alpha[i].letter == word[0])
return containsWordHelper(w->alpha[i].next, word.substr(1));
else if (word[0] == '0') //if '0' then step over and continue searching for valid path
containsWordHelper(w->alpha[i].next, word.substr(1)); //removed return here to allow looping through all the possible paths
} //I think it is continuing through after the loop and triggering return false
}
return false; //if char is missing - meaning the exact code is not there
}
The problem is that this returns false when a '0' wildcard is used. What is going wrong here? My knowledge is limited.
I hacked on this problem for awhile and used the 'howboutthis howboutthat' approach, and found that placing the return at the end of the step over statement works.
bool Lexicon::containsWordHelper(nodeT *w, string word, int &time, int &wag, string compare) //check if prefix can be combined
{
if(word == "") { //base case: all letters found
if ((w->begin-wag) <= time && time <= (w->end+wag))
return w->isWord; // case 2: timecard check for high/low date range
else if (time == ConvertDateToEpoch(9999, 01, 01)) return w->isWord; //this is for single code lookup w/o date
} else {
for(int i = 0; i < w->alpha.size(); i++) { //Loop through all of the children of the current node
if (w->alpha[i].letter == word[0])
return containsWordHelper(w->alpha[i].next, word.substr(1), time, wag, compare);
else if (word[0] == 'ž')
if (containsWordHelper(w->alpha[i].next, word.substr(1), time, wag, compare)) return true;
}
}
return false; //if char is missing - meaning the exact code is not there
}
It seems logical that if I only one the path that ends in true to return then I should place the return after the recursion is done and then conditionally pass back only if true. It works and seems logical in retrospect, but my confidence in this is sketchy at best.
I still have the same question. What is/was going wrong?
You could test the result of the latter containsWordHelper call and return true if the result is true, else continue iterating.
Solved: place a return after an if statement containing the recursive call
bool Lexicon::containsWordHelper(nodeT *w, string word)
{
if(word == "") return w->isWord;
else {
for(int i = 0; i < w->alpha.size(); i++) {
if (w->alpha[i].letter == word[0])
return containsWordHelper(w->alpha[i].next, word.substr(1));
else if (word[0] == 'ž')
if (containsWordHelper(w->alpha[i].next, word.substr(1))) return true;
}
}
return false;
}