Solve Sudoku using Back tracking Algorithm in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I had a feel to solve sudoku using C programming in early October, and soon I came to know its no easy task. Currently, I did write a code to do all the functioning but there seems to be an error somewhere which is preventing the desired result to get printed or even get evaluated.
I use the algorithm provided here as a reference to develop my code,
This is the code which I have written and correcting the error would be greatly appreciated
#include <stdio.h>
int row(int i,int j,int a[9][9]);
int column(int i,int j,int a[9][9]); //function declaration's
int grid(int i,int j,int a[9][9]);
int main()
{
int a[9][9];
int i,j,x;
for (i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
a[i][j]=0;/*for making all the array values = 0*/
/*So that the stored garbage values will be removed*/
}
}
/*Entering known elements*/
printf("Enter the elements of known elements leaving the unknown as 0\n");
for (i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
scanf("%d",&a[i][j]);
}
}
//If a given grid is '0', lets assign a value 1 and if 1 exists in the same row or column or in ints correspond 3x3 box, increment the value upto 9
i=0,j=0,x=1;
incr:
if ( a[i][j] == 0)
{
a[i][j] = x;
if( row(i,j,a) && column(i,j,a) && grid(i,j,a) )
{
a[i][j] = x;
}
else
{
x++;
if ( x>9)
x = 1;
}
}
else
{
while(i < 9)
{
i++;
goto incr;
}
if (i == 9)
{
i =1;
j++;
goto incr;
}
if (j == 9)
{
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}
}
}
int row(int i,int j,int a[9][9])
{
int m;
for(m=0;m<9;m++)
{
if( m != j)
{
if(a[i][j] == a[i][m])
{
return 0;
}
}
}
return 1;
}
int column(int i,int j, int a[9][9])
{
int m;
printf("%d%d",i,j);
for(m=0;m<9;m++)
{
if ( m != i)
{
if(a[i][j] == a[m][j])
{
return 0;
}
}
}
return 1;
}
int grid(int i,int j, int a[9][9])
{
int m,n;
if( i>=0 && i<=2 && j>=0 && j<=2) /* grid 1*/
{
for(m=0;m<=2;m++)
{
for(n=0;n<=2;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=0 && i<=2 && j>=3 && j<=5) /* grid 2*/
{
for(m=0;m<=2;m++)
{
for(n=3;n<=5;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=0 && i<=2 && j>=6 && j<=8) /* grid 3*/
{
for(m=0;m<=2;m++)
{
for(n=6;n<=8;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=3 && i<=5 && j>=0 && j<=2) /* grid 4*/
{
for(m=3;m<=5;m++)
{
for(n=0;n<=2;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=3 && i<=5 && j>=3 && j<=5) /* grid 5*/
{
for(m=3;m<=5;m++)
{
for(n=3;n<=5;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=3 && i<=5 && j>=6 && j<=8) /* grid 6*/
{
for(m=3;m<=5;m++)
{
for(n=6;n<=8;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=6 && i<=8 && j>=0 && j<=2) /* grid 7*/
{
for(m=6;m<=8;m++)
{
for(n=0;n<=2;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=6 && i<=8 && j>=3 && j<=5) /* grid 8*/
{
for(m=6;m<=8;m++)
{
for(n=3;n<=5;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
if( i>=6 && i<=8 && j>=6 && j<=8) /* grid 9*/
{
for(m=6;m<=8;m++)
{
for(n=6;n<=8;n++)
{
if(i != m && j != n)
{
if(a[i][j] == a[m][n])
{
return 0;
}
}
}
}
return 1;
}
return 0;
}

Your program exits after inserting a value in the matrix. After setting the value of a position in Line 41: a[i][j] = x;, you need to increment your i or j accordingly and then call goto incr;.
PS.: Learn to use simple printf() statements, they are great debuggers.

Related

C language- C90-printing multiple copies of specific shape next to each other

I have created a program which takes as an input:
a number which determines the shape the user wants to be printed,lets say copies
a number which the determines the 'size' of the shape
and a number which determines how many times the shape will be printed..
What I have tried is a for loop in main() function below each 'if' but the copies are printed one down another..I also came up with the idea of printing the first line <'copies'> times with the necessary padding but that practice seems to be different for every shape (and yes I cannot implement this logic in my code)...What can I do?
/*
Version 5*/
#include <stdio.h>
#include <stdio.h>
int getchoice(void);
int getsize(void);
void oof(int size,int copies);
void printrhombus(int size);
void printrighttriangle(int size);
void printisoscelestriangle(int size);
void printspace(void);
void printsymbol(void);
void printnewline(void);
void printrowno(int i);
int getcopies(void);
int main(void)
{
int choice = 0;
int size;
int copies;
for(; (choice = getchoice()) != -1 ;)
{
size = getsize();
copies = getcopies();
if(choice == 0)
{
oof(size,copies);
}
else if(choice == 1)
{
printrhombus(size);
}
else if(choice == 2)
{
printrighttriangle(size);
}
else if (choice == 3)
{
printisoscelestriangle(size);
}
}
return 0;
}
int getchoice(void)
{
int choice;
printf("Please enter which shape you want to be printed (0-3):\n");
scanf("%d",&choice);
printf("Your choice is %d\n",choice);
return choice;
}
int getsize(void)
{
int size;
printf("Please enter the number of rows-the size of your shape:\n");
scanf("\n%d",&size);
printf("Your size is %d\n",size);
return size;
}
void oof(int size,int copies)
{
int i,j,k,l;
for(i = 0; i< size; i++)
{
for(l = 0; l<copies; l++)
{
for(j = 0;j<i;j++)
{
printsymbol();
}
}
for(k =0;k<size;k++)
{
if(k == 0 || i == 0 || k == size-1 || i == size-1)
{
printrowno(i);
}
else printsymbol();
}
printnewline();
}
}
void printrhombus(int size)
{
int i,j;
int rows1 = (size/2)+1;
for(i = 1;i<=rows1;i++)
{
for(j = 1;j<=((2*rows1)-1);j++)
{
if((j==(rows1+(i-1))) || j==(rows1-(i-1)))
{
printrowno(i);
}
else if(j>rows1+i-1)
{
printspace();
}
else if(j<rows1+i-1 && j!= rows1+1-i)
{
printsymbol();
}
}
printnewline();
}
for(i = rows1-1;i>=1;i--)
{
for(j=1;j<=((2*rows1)-1);j++)
{
if((j==(rows1+(i-1))) || j==(rows1-(i-1)))
{
printrowno(size-i+1);
}
else if(j>rows1+i-1)
{
printspace();
}
else if(j<rows1+i-1 && j!= (rows1+1-i))
{
printsymbol();
}
}
printnewline();
}
}
void printrighttriangle(int size)
{
int rowno,colno;
for(rowno = 1; rowno<=size; rowno++)
{
for(colno = 1; colno<= rowno; colno++)
{
if ((colno==1) || (rowno == size) || colno == rowno)
{
printrowno(rowno);
}
else if(colno>rowno)
{
printspace();
}
else
{
printsymbol();
}
}
printnewline();
}
}
void printisoscelestriangle(int size)
{
int i,j;
for(i = 1; i<= size; i++)
{
for(j = 1;j<= ((2*size)-1);j++)
{
if(j ==(size-(i-1)) ||j == (size+(i-1))|| i == size)
{
printrowno(i);
}
if (j<size-(i-1))
{
printspace();
}
if(j>(size-(i-1)) && j<(size +(i-1))&& i!= size)
{
printsymbol();
}
}
printnewline();
}
}
void printspace(void)
{
printf(" ");
return;
}
void printsymbol(void)
{
printf("-");
return;
}
void printrowno(int i)
{
printf("%d",i);
}
void printnewline(void)
{
printf("\n");
return;
}
int getcopies(void)
{
int copies;
printf("Please enter number of copies:\n");
scanf("\n%d",&copies);
return copies;
}

Minesweeper in C [closed]

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 4 years ago.
Improve this question
The game works perfectly, but I want to add a timer that measures and shows at the end of the game, the time the player's game lasted.
The code is a classic game of minesweeper where the user gives the coordinates of the point he wants to discover from the board, the game is made in c, not in C#.
The game consists of clearing all the squares of a two-dimensional arrangement that do not hide a mine. Some squares will have a random mine while others will not. The user is asked to position a box in the two-dimensional arrangement, if he does not find a mine he will continue the game until he wins, otherwise he will finish the game and the user will lose.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define FLUSH fflush(stdin)
void difficulty( void );
void beginner( void );
void intermediate( void );
void expert( void );
void minefield_generator( void );
void print_minefield( void );
void guess( void );
void boom( void );
void print_final_minefield( void );
void win( void );
void play_again( void );
void game_over( void );
int x, y;
int M, N;
float diff;
int total_mines = 0;
int mines = 0;
int minefield[30][30]; //This 2-D array contains all of the mines, numbers and blank spaces
int blank_minefield[30][30]; //This contains the minefield full of '|-|' characters
int final_minefield[30][30];
int main()
{
printf("\t\tWelcome to Minesweeper\n");
difficulty();
return 0;
}
void difficulty( void ) //Function for choosing the difficulty level
{
diff = 0;
while( (diff != 1) && (diff != 2) && (diff != 3) && (diff != 4))
{
printf("\t\tChoose a difficulty level(1-3) or 4 for a custom game:");
scanf("%f", &diff);
FLUSH;
if( (diff != 1) && (diff != 2) && (diff != 3) && (diff != 4))
{
printf("\t\tPlease enter either 1, 2, 3 or 4\n");
}
}
if( diff == 1 ) //If, else if and else statements that each go to the respective difficulty
{
beginner();
}
else if( diff == 2 )
{
intermediate();
}
else if( diff == 3 )
{
expert();
}
else if( diff == 4)
{
custom();
}
}
void beginner( void ) //Gives the minefield the 'beginner' grid and mines
{
M = 9;
N = 9;
total_mines = 10;
minefield_generator();
guess();
}
void intermediate( void ) //Gives the minefield the 'intermediate' grid and mines
{
M = 16;
N = 16;
total_mines = 40;
minefield_generator();
guess();
}
void expert( void ) //Gives the minefield the 'expert' grid size and mines
{
M = 16;
N = 30;
total_mines = 99;
minefield_generator();
guess();
}
void custom( void )
{
M = 0;
N = 0;
total_mines = 0;
printf("\t\tPlease enter the size of the dimensions you want\n");
printf("\t\tFirst value:\n");
scanf("%d", &M);
printf("\t\tSecond value:\n");
scanf("%d", &N);
printf("\t\tNumber of mines you want to assign to the board:\n");
scanf("%d", &total_mines);
minefield_generator();
guess();
}
void minefield_generator( void ) //Function that generates the minefield
{
int i = 0, j = 0;
srand( time( NULL ) ); //Starts the random no. generator
while( j < N ) //Nested loop for making the blank minefield and final minefield
{
while( i < M)
{
minefield[i][j] = '-';
blank_minefield[i][j] = minefield[i][j];
final_minefield[i][j] = minefield[i][j];
i++;
}
i = 0;
j++;
}
mines = 0;
while( mines < total_mines ) //Randomly generates the mines into the minefield
{
i = rand()%(M);
j = rand()%(N);
if( minefield[i][j] != '*') //If statement that checks if there is a mine already there and doesn't place a mine if there is
{
minefield[i][j] = '*';
final_minefield[i][j] = minefield[i][j];
mines++;
}
}
i = 0;
j = 0;
while( j < N ) //While loop that generates the numbers for any adjacent mines
{
while( i < M)
{
if( minefield[i][j] != '*')
{
minefield[i][j] = 0;
}
if((minefield[i-1][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i-1][j] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i-1][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
i++;
}
i = 0;
j++;
}
i = 0;
j = 0;
}
void print_minefield(void) // This function prints the minefield
{
int i = 0, j = 0, z = 0;
while( z < M ) // This while loop prints out the line of co-ordinates along the x axis of the minefield
{
if( z == 0 )
{
printf("\t");
}
printf("|%d|\t", z);
z++;
}
printf("\n\n");
while( j < N ) // Loop that prints out each character in the minefield
{
printf("|%d|\t", j);
while( i < M)
{
if( blank_minefield[i][j] == '-')
{
printf("|%c|\t", blank_minefield[i][j]);
}
else if( minefield[i][j] == 0 ) // This changes any spaces with values of zero to the character 'B'
{
blank_minefield[i][j] = 'B';
printf("|%c|\t", blank_minefield[i][j]);
}
else
{
printf("|%d|\t", blank_minefield[i][j]);
}
i++;
}
printf("\n");
i = 0;
j++;
}
}
void guess( void )
{
int q = 0, i=0, j=0, match=0;
print_minefield();
while( j < N ) // While loop for testing whether or not the user has cleared the minefield
{
while( i < M )
{
if(minefield[i][j] == blank_minefield[i][j])
{
match++;
}
i++;
}
i = 0;
j++;
}
if( match == (( M * N ) - total_mines)) // If the user has cleared the minefield, the win() function is run
{
win();
}
printf("\nEnter the x value, then a space, then the y value:");
scanf("%d %d", &x, &y); // Reading in the co-ordinates for the guess
FLUSH;
if( (x >= M) || (x < 0) || (y < 0) || (y >= N) )
{
printf("\nPlease enter a value inside the grid\n");
guess();
}
if( minefield[x][y] == '*' ) // Runs the boom() function if the user selects a mine
{
boom();
}
if( blank_minefield[x][y] != '-' )
{
printf("\nPlease enter a value that has not already been entered\n");
guess();
}
else // Checks if the adjacent spaces are blank, then changes the values in the blank_minefield array. Because they are changed, they will now print out in the print_minefield function
{
blank_minefield[x][y] = minefield[x][y];
if( minefield[x][y] == 0 )
{
if( minefield[x-1][y-1] == 0 )
{
blank_minefield[x-1][y] = minefield[x-1][y];
}
if( minefield[x-1][y] == 0 )
{
blank_minefield[x-1][y] = minefield[x-1][y];
}
if( minefield[x][y-1] == 0 )
{
blank_minefield[x][y-1] = minefield[x][y-1];
}
if( minefield[x-1][y+1] == 0 )
{
blank_minefield[x-1][y+1] = minefield[x-1][y+1];
}
if( minefield[x+1][y-1] == 0 )
{
blank_minefield[x+1][y-1] = minefield[x+1][y-1];
}
if( minefield[x+1][y] == 0 )
{
blank_minefield[x+1][y] = minefield[x+1][y];
}
if( minefield[x][y+1] == 0 )
{
blank_minefield[x][y+1] = minefield[x][y+1];
}
if( minefield[x+1][y+1] == 0 )
{
blank_minefield[x+1][y+1] = minefield[x+1][y+1];
}
}
guess();
}
}
void boom( void ) // Runs the print_final_minefield function, then the play_again function
{
print_final_minefield();
printf("\n\t\tYou hit a mine at %d,%d\n\t\tYOU LOSE!!!!", x, y);
play_again();
}
void print_final_minefield( void ) // Prints the minefield, showing where all of the mines are placed
{
int i = 0, j = 0, z = 0;
while( z < M )
{
if( z == 0 )
{
printf("\t");
}
printf("|%d|\t", z);
z++;
}
printf("\n\n");
while( j < N )
{
printf("|%d|\t", j);
while( i < M)
{
printf("|%c|\t", final_minefield[i][j]);
i++;
}
printf("\n");
i = 0;
j++;
}
}
void win( void ) // Runs the play_again function
{
printf("\n\n\n\t\t\tYOU WIN!!!!!\n\n\n");
play_again();
}
void play_again( void ) // Gives the user the option to play again
{
char option[2];
printf("\n\t\tWould you like to play again(Y/N)?:");
scanf("%c", &option[0]);
FLUSH;
if((option[0] == 'Y') || (option[0] == 'y')) // Restarts the program from after the welcome message
{
difficulty();
}
else if( (option[0] == 'N') || (option[0] == 'n'))
{
game_over();
}
else
{
printf("Please enter either Y or N");
play_again();
}
}
void game_over( void ) // Ends the program
{
printf("\n\n\t\tGame Over");
exit(1);
}
Use the function clock() to catch the moment’s clock, and then use the macro CLOCKS_PER_SEC to calculate how many second has gone by. Like this:
int timeInSeconds;
clock_t start = clock(), end,total;
...
end = clock();
total = end - start;
timeInSeconds = total/CLOCKS_PER_SEC;

16*16 Sudoku solver using backtracking in c

I have coded a 16*16 sudoku solver using the backtracking algorithm in c. The program takes input from the user using a text file. The unfilled positions in the matrix are filled with a 0. Works perfectly fine.
I want to further optimize the code for time and space complexity. Please suggest some methods or ways to optimize the code.
#include <stdio.h>
#include<time.h>
#define N 16
int isAvailable(int sudoku[16][16], int row, int col, int num)
{
int i, j;
for(i=0; i<16; i++){
if( (sudoku[row][i] == num) || ( sudoku[i][col] == num ) )
return 0;
}
int rowStart = (row/4) * 4;
int colStart = (col/4) * 4;
for(i=rowStart; i<(rowStart+4); ++i)
{
for(j=colStart; j<(colStart+4); ++j)
{
if( sudoku[i][j] == num )
return 0;
}
}
return 1;
}
int fillsudoku(int sudoku[16][16], int row, int col)
{
int i;
if( row<16 && col<16 )
{
if( sudoku[row][col] != 0 )
{
if( (col+1)<16 )
return fillsudoku(sudoku, row, col+1);
else if( (row+1)<16 )
return fillsudoku(sudoku, row+1, 0);
else
return 1;
}
else
{
for(i=0; i<16; ++i)
{
if( isAvailable(sudoku, row, col, i+1) )
{
sudoku[row][col] = i+1;
if( (col+1)<16 )
{
if( fillsudoku(sudoku, row, col+1) )
return 1;
else
sudoku[row][col] = 0;
}
else if( (row+1)<16 )
{
if( fillsudoku(sudoku, row+1, 0) )
return 1;
else
sudoku[row][col] = 0;
}
else
return 1;
}
}
}
return 0;
}
else
{
return 1;
}
}
int main()
{
clock_t tic=clock();
int a,i,j;
int sudoku[N][N];
FILE *f;
f=fopen("s16.txt","r");
for(i=0;i<N;i++){
for(j=0;j<N;j++)
{
fscanf(f,"%d",&sudoku[i][j]);
}
}
if( fillsudoku(sudoku, 0, 0) )
{
for(i=0; i<16; ++i)
{
for(j=0; j<16; ++j){
printf("%d ", sudoku[i][j]);
if(sudoku[i][j]<10){
printf(" ");
}
if(j%4==3){
printf("|");
}
}
printf("\n");
if(i%4==3){
printf("----------------------------------------------------");
}
printf("\n");
}
}
else
{
printf("\n\nNO SOLUTION\n\n");
}
clock_t toc=clock();
printf("\nTotal time elasped is %f", (double)(toc - tic) / CLOCKS_PER_SEC);
return 0;
fclose(f);
}

Pointers Binary Tree Maze Solver in C

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

C Recursive WordSearch solver in all directions

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?

Resources