I need to create a Robot Simulator programmed in C. The Robot has to find the Exit of a 2d labirinth using a Recursive Backtracker algorithm, i understood how does this algorithm work but i don't know how to implement it. I Think i can use a Binary Tree using Pointers but i don't know how to do this, can you try to explain it to me?
This is the program that i've created, now the Robot is entering a loop because of the method that changes direction
#ifdef __unix__
#include <unistd.h>
#elif defined _WIN32
#include <windows.h>
#define sleep(x) Sleep(1000 * x)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void goUp();
void goDown();
void goLeft();
void goRight();
typedef struct robot {
int direction;
bool is_moving;
}robot;
typedef struct room {
robot robot;
bool is_robot;
int obstacle;
}room;
room Room[20][20];
int r = 12;
int c = 10;
void generation(room matrix[20][20])
{
srand(time(NULL));
int x,i,j;
x=0;
for(i=0;i<20;i++)
{
for(j=0;j<20;j++)
{
matrix[i][j].is_robot=false;
x=rand()%100+1;
if(x==1||x==50||x==100)
{
matrix[i][j].obstacle=1;
}
else
{
matrix[i][j].obstacle=0;
}
}
}
}
void print_matrix(room matrix[20][20])
{
int i,j;
for(i=0;i<20;i++)
{
for(j=0;j<20;j++)
{
if(matrix[i][j].obstacle==0)
{
if(matrix[i][j].is_robot==true)
{
printf("I");
}
else
{
printf(" ");
}
}
else
{
if(matrix[i][j].is_robot==true)
{
printf("I");
}
else
{
printf("o");
}
}
}
printf("\n");
}
}
bool changeDirection(room Room[20][20],int i,int j)
{
if(Room[i][j].robot.direction == 1)
{
if(Room[i-1][j].obstacle == 1 || i-1 == 0)
{
if(Room[i+1][j].obstacle == 1 || i+1 == 19)
{
Room[i][j].robot.direction = 2;
return true;
}
else
{
Room[i][j].robot.direction = 4;
return true;
}
}
else
{
Room[i][j].robot.direction = 3;
return true;
}
}
if(Room[i][j].robot.direction == 2)
{
if(Room[i-1][j].obstacle == 1 || i-1 == 0)
{
if(Room[i+1][j].obstacle == 1 || i+1 == 19)
{
Room[i][j].robot.direction = 1;
return true;
}
else
{
Room[i][j].robot.direction = 4;
return true;
}
}
else
{
Room[i][j].robot.direction = 3;
return true;
}
}
if(Room[i][j].robot.direction == 3)
{
if(Room[i][j+1].obstacle == 1 || j+1 == 19)
{
if(Room[i][j-1].obstacle == 1 || j-1 == 0)
{
Room[i][j].robot.direction = 4;
return true;
}
else
{
Room[i][j].robot.direction = 2;
return true;
}
}
else
{
Room[i][j].robot.direction = 1;
return true;
}
}
if(Room[i][j].robot.direction == 4)
{
if(Room[i][j+1].obstacle == 1 || j+1 == 19)
{
if(Room[i][j-1].obstacle == 1 || j-1 == 0)
{
Room[i][j].robot.direction = 3;
return true;
}
else
{
Room[i][j].robot.direction = 2;
return true;
}
}
else
{
Room[i][j].robot.direction = 1;
return true;
}
}
}
void goRight()
{
c=c+1;
Room[r][c].robot.direction=1;
Room[r][c].is_robot=true;
Room[r][c-1].is_robot=false;
}
void goLeft()
{
c=c-1;
Room[r][c].robot.direction=2;
Room[r][c].is_robot=true;
Room[r][c+1].is_robot=false;
}
void goUp()
{
r=r-1;
Room[r][c].robot.direction=3;
Room[r][c].is_robot=true;
Room[r+1][c].is_robot=false;
}
void goDown()
{
r=r+1;
Room[r][c].robot.direction=4;
Room[r][c].is_robot=true;
Room[r-1][c].is_robot=false;
}
int main()
{
generation(Room);
Room[r][c].robot.direction = 1;
Room[r][c].robot.is_moving = true;
Room[r][c].is_robot = true;
do
{
Room[r][c].robot.is_moving = true;
if (Room[r][c].robot.direction == 1 && Room[r][c].robot.is_moving == true) // destra
{
if(Room[r][c +1].obstacle == 1 || c+1 == 19)
{
changeDirection(Room,r,c);
}
else
{
goRight();
}
}
if (Room[r][c].robot.direction == 2 && Room[r][c].robot.is_moving == true) // sinistra
{
if(Room[r][c -1].obstacle == 1 || c-1 == 0)
{
changeDirection(Room,r,c);
}
else
{
goLeft();
}
}
if (Room[r][c].robot.direction == 3 && Room[r][c].robot.is_moving == true) // su
{
if(Room[r-1][c].obstacle == 1 || r-1 == 0)
{
changeDirection(Room,r,c);
}
else
{
goUp();
}
}
if (Room[r][c].robot.direction == 4 && Room[r][c].robot.is_moving == true) // giu
{
if(Room[r+1][c].obstacle == 1 || r+1 == 19)
{
changeDirection(Room,r,c);
}
else
{
goDown();
}
}
print_matrix(Room);
sleep(0.1);
system("cls");
}
while(1);
print_matrix(Room);
}
I'm having a hard time understanding how a binary tree would be useful in finding a path in a labyrinth (maybe it's used to represent the labyrinth?) but maybe I'm blind. I would simply make a 2d int array and let 0 mean the position is blocked (there's a wall there or something) and 1 mean it's open (you can move there). The brute force backtrack procedure, going off orthogonal movement (left, right, up, down) would be:
f(x,y){
// you found the place your want to go to
if (x,y) is (destinationX,destinationY)
return true
block the position (x,y) // i.e. mark current position as visited
if there is an open spot at (x,y-1) AND f(x,y-1)
return true
if there is an open spot at (x,y+1) AND f(x,y+1)
return true
if there is an open spot at (x-1,y) AND f(x-1,y)
return true
if there is an open spot at (x+1,y) AND f(x+1,y)
return true
return false
}
Suppose you had the labyrinth looking like:
"+" is where you start ([1][1])
"-" is your destination ([3][1])
"#" is a blocked region
===========
|#|#|#|#|#|
|#|+| |#|#|
|#|#| |#|#|
|#|-| | |#|
|#|#|#|#|#|
===========
Using the above idea I have:
#include <stdio.h>
#define width 5
#define height 5
// print maze
void print(char arr[][width]){
for (int i = 0; i < 2*width+1; i++) printf("=");
printf("\n");
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
printf("|%c",arr[i][j]);
}
printf("|\n");
}
for (int i = 0; i < 2*width+1; i++) printf("=");
}
// starting from (x,y) to (destX,destY)
int path(int arr[][width],int x,int y,int destX,int destY,char toDest[][width]){
if (x==destX && y==destY) {
toDest[y][x] = '*';
print(toDest);
return 1;
}
// mark current position as visited
arr[y][x] = 0;
toDest[y][x] = '*';
// left
if (arr[y][x-1] && path(arr,x-1,y,destX,destY,toDest))
return 1;
// right
if (arr[y][x+1] && path(arr,x+1,y,destX,destY,toDest))
return 1;
// up
if (arr[y-1][x] && path(arr,x,y-1,destX,destY,toDest))
return 1;
// down
if (arr[y+1][x] && path(arr,x,y+1,destX,destY,toDest))
return 1;
return 0;
}
int main () {
// use this to store path
// and then print it out if found
char toDest[height][width] = {
{'#','#','#','#','#'},
{'#',' ',' ','#','#'},
{'#','#',' ','#','#'},
{'#',' ',' ',' ','#'},
{'#','#','#','#','#'}
};
// 0 -> position is blocked
// 1 -> position is open
int maze[height][width] = {
{0,0,0,0,0},
{0,1,1,0,0},
{0,0,1,0,0},
{0,1,1,1,0},
{0,0,0,0,0}
};
path(maze,1,1,1,3,toDest);
}
Output:
===========
|#|#|#|#|#|
|#|*|*|#|#|
|#|#|*|#|#|
|#|*|*| |#|
|#|#|#|#|#|
===========
In output the path is designated by the *s
In the main file, I loop through each line of input until it hits the words, then I pass the word its searching for to startSearch with puzzleArray, the solvedArray I want to get back, the word as string, size as number of rows, and length as number of columns.
Currently, I keep getting segmentation faults/or endless loops. Any help over my algorithm/code would be greatly appreciated.
void startSearch(char** puzzleArray,char** solvedArray,char* string,int size,int length)
{
char* direction = "";
int solved = 1;
int j = 0;
while( j <= 7 && solved != 0)
{
if(j == 0)
{
direction = "up";
}
else if(j == 1)
{
direction = "upRight";
}
else if(j == 2)
{
direction = "right";
}
else if(j == 3)
{
direction = "downRight";
}
else if(j == 4)
{
direction = "down";
}
else if(j == 5)
{
direction = "downLeft";
}
else if(j == 6)
{
direction = "left";
}
else if(j == 7)
{
direction = "upLeft";
}
solved = recursiveSearch(puzzleArray,solvedArray,string,direction,size,length,0,0,0);
j++;
}
}
int recursiveSearch(char** puzzleArray,char** solvedArray,char* string,char* direction,int sizeOfPuzzle,int lengthOfArrayWithSpaces,int rowPos,int colPos,int stringPosition)
{
int lengthOfWord;
int i = rowPos;
int j = colPos;
int found = 0;
int empty = 1;
char c = string[stringPosition];
int position = stringPosition;
lengthOfWord = lengthOfArray(string);
if(string[position+1] == '\0')
{
return 0;
}
while(empty != 0)
{
if(string[stringPosition] == puzzleArray[i][j])
{
found = 1;
}
else if(rowPos < sizeOfPuzzle && colPos < lengthOfArrayWithSpaces)
{
stringPosition = 0;
for(i = rowPos; i < sizeOfPuzzle && found != 1; i++)
{
for(j = colPos; j < puzzleArray[rowPos][colPos] != '\0' && found != 1; j++)
{
if(string[stringPosition] == puzzleArray[i][j])
{
found = 1;
rowPos = i;
colPos = j;
stringPosition = 0;
}
}
}
if(found == 0)
{
empty = 1;
}
}
if(found == 1)
{
position = stringPosition + 1;
if(rowPos-1 >= 0)
{
//printf("\nString:%cPuzzleArray:%c",string[position],puzzleArray[rowPos-1][colPos]);
if(string[position] == puzzleArray[rowPos-1][colPos] && direction == "up")
{
//printf("UP");
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos-1,colPos,position+1))
{
solvedArray[rowPos-1][colPos] = puzzleArray[rowPos-1][colPos];
return 0;
}
}
else if(colPos+2 <= lengthOfArrayWithSpaces)
{
if(string[position] == puzzleArray[rowPos-1][colPos+2] && direction == "upRight")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos-1,colPos+2,position+1))
{
solvedArray[rowPos-1][colPos+2] = puzzleArray[rowPos-1][colPos+2];
return 0;
}
}
}
}
if(colPos+2 <= lengthOfArrayWithSpaces)
{
if(string[position] == puzzleArray[rowPos][colPos+2] && direction == "right")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos,colPos+2,position+1))
{
solvedArray[rowPos][colPos+2] = puzzleArray[rowPos][colPos+2];
return 0;
}
}
if(rowPos+1 <= lengthOfArrayWithSpaces)
{
if(string[position] == puzzleArray[rowPos+1][colPos+2] && direction == "downRight")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos+1,colPos+2,position+1))
{
solvedArray[rowPos+1][colPos+2] = puzzleArray[rowPos+1][colPos+2];
return 0;
}
}
}
}
if(rowPos+1 <= sizeOfPuzzle)
{
if(string[position] == puzzleArray[rowPos+1][colPos] && direction == "down")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos+1,colPos,position+1))
{
solvedArray[rowPos+1][colPos] = puzzleArray[rowPos+1][colPos];
return 0;
}
}
if(rowPos + 1 <= lengthOfArrayWithSpaces)
{
if(string[position] == puzzleArray[rowPos+1][colPos-2] && direction == "downLeft")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos+1,colPos-2,position+1))
{
solvedArray[rowPos+1][colPos-2] = puzzleArray[rowPos+1][colPos-2];
return 0;
}
}
}
}
if(colPos-2 >= 0)
{
if(string[position] == puzzleArray[rowPos][colPos-2] && direction == "left")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos+1,colPos+2,position+1))
{
solvedArray[rowPos+1][colPos+2] = puzzleArray[rowPos+1][colPos+2];
return 0;
}
}
if(rowPos - 1 >= 0)
{
if(string[position] == puzzleArray[rowPos-1][colPos-2] && direction == "upLeft")
{
if(recursiveSearch(puzzleArray,solvedArray,string,direction,sizeOfPuzzle,lengthOfArrayWithSpaces,rowPos-1,colPos-2,position+1))
{
solvedArray[rowPos-1][colPos-2] = puzzleArray[rowPos-1][colPos-2];
return 0;
}
}
}
}
}
}
return 1;
}
direction == "up"
This is not how you compare two strings to be equal. Use strcmp / strncmp for string comparison. This kind of comparison appears all over your code.
Also:
for(j = colPos; j < puzzleArray[rowPos][colPos] != '\0' && found != 1; j++)
This j < puzzleArray[rowPos][colPos] != '\0' looks dubious, what are you trying to do?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Let me start by saying I know this is not the most efficient way of writing this program, but this is the way I've done it, sloppy or not, I just need help understanding why I cannot grab values from my array.
If you run this monstrosity, it will spit out 0s for i and t, my temporary variables. I'm not done setting up all the bug stops, but that is not a my issue. I'm just confused and lost as to why I cannot grab values from my arrays and assign them to new variables. Any input would be GREATLY appreciated. Thank you.
#include <stdio.h>
int main(void)
{
int day1, day2, mnth1, mnth2;
int x, y, i, t;
int jan[31] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
int feb[28] = {32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59};
int mar[31] = {60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90};
int apr[30] = {91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120};
int may[31] = {121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151};
int jun[30] = {152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181};
int jul[31] = {182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212};
int aug[31] = {213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243};
int sep[30] = {244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273};
int oct[31] = {274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304};
int nov[30] = {305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334};
int dec[31] = {335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365};
printf("Please enter the information that is asked only\n");
printf("Please enter the first date: ");
scanf("%d", &mnth1);
scanf("%d", &day1);
printf("%d", mnth1);
printf(" ");
printf("%d\n", day1);
if (mnth1 < 1 | day1 < 1) {
return 0;
}
if (mnth1 == 1) {
if (day1 = jan[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 2) {
if (day1 = feb[i]) {
x = i + 1;
} else if (day1 > 28) {
return 0;
}
} else if (mnth1 == 3) {
if (day1 = mar[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 4) {
if (day1 = apr[i]) {
x = i + 1;
} else if (day1 > 30) {
return 0;
}
} else if (mnth1 == 5) {
if (day1 = may[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 6) {
if (day1 = jun[i]) {
x = i + 1;
} else if (day1 > 30) {
return 0;
}
} else if (mnth1 == 7) {
if (day1 = jul[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 8) {
if (day1 = aug[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 9) {
if (day1 = sep[i]) {
x = i + 1;
} else if (day1 > 30) {
return 0;
}
} else if (mnth1 == 10) {
if (day1 = oct[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 == 11) {
if (day1 = nov[i]) {
x = i + 1;
} else if (day1 > 30) {
return 0;
}
} else if (mnth1 == 12) {
if (day1 = dec[i]) {
x = i + 1;
} else if (day1 > 31) {
return 0;
}
} else if (mnth1 > 12) {
return 0;
}
printf("Please enter the second date: ");
scanf("%d", &mnth2);
scanf("%d", &day2);
printf("%d", mnth2);
printf(" ");
printf("%d\n", day2);
if (mnth2 == 1) {
if (day2 = jan[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 2) {
if (day2 = feb[t]) {
y = t + 1;
} else if (day2 > 28) {
return 0;
}
} else if (mnth2 == 3) {
if (day2 = mar[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 4) {
if (day2 = apr[t]) {
y = t + 1;
} else if (day2 > 30) {
return 0;
}
} else if (mnth2 == 5) {
if (day2 = may[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 6) {
if (day2 = jun[t]) {
y = t + 1;
} else if (day2 > 30) {
return 0;
}
} else if (mnth2 == 7) {
if (day2 = jul[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 8) {
if (day2 = aug[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 9) {
if (day2 = sep[t]) {
y = t + 1;
} else if (day2 > 30) {
return 0;
}
} else if (mnth2 == 10) {
if (day2 = oct[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 == 11) {
if (day2 = nov[t]) {
y = t + 1;
} else if (day2 > 30) {
return 0;
}
} else if (mnth2 == 12) {
if (day2 = dec[t]) {
y = t + 1;
} else if (day2 > 31) {
return 0;
}
} else if (mnth2 > 12) {
return 0;
}
printf("The difference between these two dates is:\n");
printf("%d\n", x);
printf("%d\n", y);
// printf("%d\n", y - x);
}
First, many of your secondary if statements are using the assignment operator = and not the comparison ==.
Second, where is i supposed to be set initially? If your goal is for x to be the value from the array, just set it: x = dec[day1]