So, I'm trying to make a maze solver with given (X, Y) coordinates of start and end positions, but I have a condition: everytime it goes from one point to another it should check if the new position is lower than the previous (a[x][y] <= some_height_variabile). Here is my code so far:
#include <stdio.h>
#define N 4
int a[N][N] =
{
{35, 75, 80, 12},
{13, 12, 11, 3},
{32, 9, 10, 8},
{12, 2, 85, 1}
};
int sol[N][N];
int h, k, count;
int end_x = -1, end_y = -1;
int start_x = -1, start_y = -1;
void print()
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (sol[i][j] > 0)
printf("%d ", sol[i][j]);
else
printf("_ ");
}
printf("\n");
}
printf("\n");
}
int solution(int x, int y)
{
return (x == end_x && y == end_y);
}
int valid(int x, int y)
{
return (x >= 0 && x < N && y >= 0 && y < N && a[x][y] <= h && !sol[x][y]);
}
void back(int x, int y)
{
if (valid(x, y))
{
k ++;
sol[x][y] = k;
h = a[x][y]; // right here I'm updating the variabile
if (solution(x, y))
{
count ++;
print();
}
else
{
back(x + 1, y);
back(x, y + 1);
back(x - 1, y);
back(x, y - 1);
}
sol[x][y] = 0;
h = a[x][y]; // I actually don't know where to put this
k --;
}
}
int main(void)
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
printf("%d ", a[i][j]);
printf("\n");
}
while (start_x >= N || start_x < 0 || start_y >= N || start_y < 0)
{
printf(">> Start X: "); scanf("%d", &start_x);
printf(">> Start Y: "); scanf("%d", &start_y);
}
h = a[start_x][start_y];
while (end_x >= N || end_x < 0 || end_y >= N || end_y < 0)
{
printf(">> End X: "); scanf("%d", &end_x);
printf(">> End Y: "); scanf("%d", &end_y);
}
printf("Generated solutions:\n");
back(start_x, start_y);
if (!count)
printf("No path was found!\n");
return 0;
}
So, for start_x
= 0, start_y
= 0, end_x
= 1, end_y
= 3 it should bring the 35 -> 13 -> 12 -> 11 -> 3 and the 35 -> 13 -> 12-> 11 -> 10 -> 8 -> 3 solutions.
Without that condition the algorithm is working fine, it's just that I don't know where to update the h
variable.
I think you are on the right track. However the variable h
seems redundant. Instead you need two more things:
1) Have you visited a particular cell before or not.
2) The value of your previous move, so when as you move to the next cell or consider moving to the next cell you verify if its a valid move.
Your modified code is as follows:
#include <stdio.h>
#define N 4
int a[N][N] =
{
{35, 75, 80, 12},
{13, 12, 11, 3},
{32, 9, 10, 8},
{12, 2, 85, 1}
};
int sol[N][N];
int visited[N][N];
int h, k, count;
int end_x = -1, end_y = -1;
int start_x = -1, start_y = -1;
void print()
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (sol[i][j] > 0)
printf("%d ", sol[i][j]);
else
printf("_ ");
}
printf("\n");
}
printf("\n");
}
int solution(int x, int y)
{
return (x == end_x && y == end_y);
}
int valid(int x, int y, int currentCellValue)
{
return (x >= 0 && x < N && y >= 0 && y < N && a[x][y] <= currentCellValue && !sol[x][y] && !visited[x][y]);
}
void back(int x, int y, int curr)
{
if (valid(x, y, curr))
{
k ++;
sol[x][y] = k;
visited[x][y] = 1;
if (solution(x, y))
{
count ++;
print();
}
else
{
back(x + 1, y, a[x][y]);
back(x, y + 1, a[x][y]);
back(x - 1, y, a[x][y]);
back(x, y - 1, a[x][y]);
}
sol[x][y] = 0;
visited[x][y] = 0;
k --;
}
}
int main(void)
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
printf("%d ", a[i][j]);
printf("\n");
}
while (start_x >= N || start_x < 0 || start_y >= N || start_y < 0)
{
printf(">> Start X: "); scanf("%d", &start_x);
printf(">> Start Y: "); scanf("%d", &start_y);
}
h = a[start_x][start_y];
while (end_x >= N || end_x < 0 || end_y >= N || end_y < 0)
{
printf(">> End X: "); scanf("%d", &end_x);
printf(">> End Y: "); scanf("%d", &end_y);
}
printf("Generated solutions:\n");
back(start_x, start_y, a[start_x][start_y]);
if (!count)
printf("No path was found!\n");
return 0;
}
During the call to back
notice how I pass the value of the current cell, which is passed to the isValid
function to make sure if the move is valid or not.
int visited[N][N];
ensures that you dont visit the same cell over and over again.