DFS algorithm maze generator - c

I'm trying to use the DFS algo to create a maze in ASCII ('#' represents a wall and ' ' a free space) that has as start the upper left corner and as exit the lower right corner. The problem is the maze starts its creation and then it's blocked because all its neighbors have been already visited.
I start at the upper left corner, mark the cell as visited and put a ' ' (it represents a free space), then I chose randomly a neighbor of the cell and I do the same. However I put this in a while loop and I'm sure this isn't the good idea.
Here my attempt of the DFS :
int generation(t_maze *maze, int pos_y, int pos_x)
{
int dest;
maze->maze[pos_y][pos_x] = ' ';
maze->visited[pos_y][pos_x] = '1';
while (maze->maze[maze->height - 1][maze->width - 1] == '#')
{
if ((dest = my_rand(1, 4)) == 1 && pos_y - 1 >= 0 && maze->visited[pos_y - 1][pos_x] == '0')
generation(maze, pos_y - 1, pos_x);
else if (dest == 2 && pos_x + 1 < maze->width && maze->visited[pos_y][pos_x + 1] == '0')
generation(maze, pos_y, pos_x + 1);
else if (dest == 3 && pos_y + 1 < maze->height && maze->visited[pos_y + 1][pos_x] == '0')
generation(maze, pos_y + 1, pos_x);
else if (dest == 4 && pos_x - 1 >= 0 && maze->visited[pos_y][pos_x - 1] == '0')
generation(maze, pos_y, pos_x - 1);
my_showtab(maze->maze); //it prints the 2d array
usleep(50000);
}
typedef struct s_maze
{
int width;
int height;
char **maze;
char **visited;
} t_maze;
In the structure,
width is the width of the maze
height is the height of the maze
maze is a 2D array that is supposed to be filled with ' ' and '#'
visited is a 2D array with 0 and 1, 0 : unvisited, 1 : visited
I want to have a maze like this (little example)
########
# #
## #
# #
#######

Your code builds one path as it always goes to only one next cell. That's not a dfs. You could do it like that:
def dfs(x, y):
visited[x][y] = true
maze[x][y] = ' '
next_cell = random unvisited neighbors of (x, y):
dfs(next_cell.x, next_cell.y)
The point is: you need to backtrack at some point (it's convenient to use recursion for it). A single path won't look the way you want (it may also get stuck and never reach the exit).

Related

why is the character not moving correctly in a dynamic 2d array?

I have troubles with moving my character.
The Program should behave like this:
Read from the input two numbers separated by a space, rows and cols.
Create a 2D grid (array) of characters with dimensions of rows rows and cols columns. Initialize the characters in the grid to '.' (dot).
Place the turtle in position (0, 0) - the zero row and the zero column (top left).
Load characters sequentially from the program input. The characters will be separated by a white character (a space or a line).
If you hit the 'x' character, print the grid to the Program Output and exit the program.
If you encounter characters '<', '>', '^', 'v', Move the turtle in the corresponding direction (Left, Right, Up, Down).
If you encounter the character 'o', enter the character' o ' in the grid at the current position of the turtle.
If the turtle were to make a move that would take it out of the grid (e.g. to position (0, 0) it would receive the command to go to the left), then “teleport” the turtle to the opposite side of the grid.
My program (I do not why but when I press ">" or "<" it moves by two, not one):
#include <stdio.h>
#include <stdlib.h>
int main(){
int rows, cols;
int i;
int j;
int x = 0, y = 0;
char symbol = 'o';
scanf("%d %d", &rows, &cols);
char* pole = (char*)malloc(rows * cols * sizeof(char));
for (i = 0; i < rows; i++){
for(j = 0; j < cols; j++)
pole[i * rows + j] = '.';
}
pole[x * rows + y] = 'o';
while(symbol != 'x'){
scanf("%c", &symbol);
if (symbol == '^') x--;
else if (symbol == 'v') x++;
else if (symbol == '>') y++;
else if (symbol == '<') y--;
else if (symbol == 'o') pole[x * rows + y] = 'o';
if(0 < y)
y = rows - 1;
else if(y > rows)
y = 0;
if(x < 0)
x = cols - 1;
else if(x > cols)
x = 0;
}
for (i = 0; i < rows; i++){
for(j = 0; j < cols; j++){
printf("%c", pole[i * rows + j]);
}
printf("\n");
}
return 0;
}
It should be like this:
3 3
o
>
v
o
>
v
o
x
o..
.o.
..o
But I have this:
3 3
o
>
v
o
>
v
o
x
o..
..o
..o
You've done a great job in your code but what's causing an error, in output is if(0<y) this if statement. Let's say you have this as your grid
and with pole[x * rows + y] = 'o'; 0,0 is already set to 'o' while your turtle stays at (0,0).
Now, with your input stream,
1: 'o' - The 'o' at (0,0) gets overwritten with'o'
2: > - y gets incremented by 1
3: v - x gets incremented by 1
so now your turtle is at (1,1) i.e. position 4 at grid but now when if(0<y) is encountered it comes to be true cause y<0 where y=1 at the moment so y is changed to y=rows-1 i.e. 2 in this case
So, now your turtle is at (0,2) i.e. position 5 at the grid, and now when 'o' is given as input it is set to 5th position of the grid.
This same thing will happen again n again with y no matter where you want it using '>', after if(0<y) y will be set to last column of the grid irrespective of the value of x
And if just in case y actually becomes less than 0 there will be an run time error in your code.
So, as it's solution you should use if(y<0) instead, in this case y will only be set to last column if user enters '<' when turtle is at anywhere in the first column of the grid.
The code seems to work as expected for the input you have given when you change if (0 < y) to if (0 > y) (i.e., the opposite relation). By the way, I would suggest you to write it if (y < 0), which is more readable, at least for me.
(Thanks, Lundin, for a hint to this line.)

Taking minimum value of neighboring cells

I'm trying to write a function that takes receives some matrix[N][M] (N and M are defined at the beginning and they're both always 3), two integers and returns the smallest value of neighboring cells (horizontally, vertically and diagonally) to that specific (y,x) cell (The function is part of a larger code that takes specific (y,x)s and not any (y,x). it is called in some specific cases) in a 2D array - Minimum(int mat[N][M], int y, int x).
Say for example I have the 2D array and I'm looking specifically at the 0,0 element
1 10 9
18 9 10
19 10 8
I want that cell to change to 9 since its the smallest value of the neighboring cells (the cell itself doesn't matter if it's the minimum of them all or not) so the array becomes
9 10 9
18 9 10
19 10 8
What I tried: First I went over each neighboring cell. After that, I mainly tried storing the value of that neighboring cell in some other variable
tmp=mat[y+i][x+j]
that changes in every iteration and then add some if condition after it which takes the minimum value to the mat[y][x]=mat[y+i][x+j] cell. I tried a lot of conditions and none worked.
Another thing I thought of and tried implementing was adding a 1D array that stores the values of the all the neighboring cells (if there are less than the size of the array - store 0) and then checking the minimum between every two cells excluding the 0s. The code got scrambled and I got lost on where I would put the loop for that array.
I went over the neighboring cells of some specific y,x cell in the following way:
Min(int mat[N][M], int y, int x)
{
for(i=-1;i<=1;i++)
{
if((y+i>=0) && (y+i<=N))
{
for(j=-1;j<=1;j++)
{
if((x+j>=0) && (x+j<=M))
{
if((x+i != 0) && (y+j != 0))
{
/*CONDITION TO TAKE MINIMUM*/
}
}
}
}
}
}
Any help would be very much appreciated.
1) matr[N][M] it doesn't have elements like matr[?][M] and matr[N][?] because numeration is from 0 to N-1 (or M-1). So you should change condition y+i<=N to y+i<N and x+j<=M to x+j<M.
2) To check that you aren't looking at the cell [y][x] itself you should check if(!(i == 0 && j == 0)) or, equivalent, if(i != 0 || j != 0) instead of if(x+i != 0 && y+j != 0)
3) To find minimum first make int min = INT_MAX; at beginning of the function. The condition to take minimum will be
if (mat[y+i][x+j] < min)
min = mat[y+i][x+j];
4) To write the minimum to the cell [y][x], use matr[y][x] = Min(matr, y, x); in main function or where you want
Alternatively you can walk through all possible cells [i][j] such a way:
int u = max(0, y - 1), d = min(y + 1, N - 1);
int l = max(0, x - 1), r = min(x + 1, M - 1);
for (i = d; i <= u; i++)
for (j = l; j <= r; j++)
if (i != y || j != x)
if (mat[i][j] < min)
min = mat[i][j];
return min;

segmentation fault because of character changement

I'm writing a board game detailed information. I get segmentation fault just changing problem_ch from ' '(space) to '.'. When I play by the moves and with ' ', I don't get but when I play by the moves and with '.'I get. I really and really don't understand what happening.
Solved: Because of negative index, I get the segmentation fault. By
handling, It is solved.
Following moves:
3d
2d
5f
2e
1e
4b
4c
4a
3b
at 4b segmentation fault
Code:
void make_move(char board[][SIZE], size_t row, size_t col, char player)
{
int rowdelta = 0; // Row increment
int coldelta = 0; // Column increment
size_t x = 0; // Row index for searching
size_t y = 0; // Column index for searching
// Identify opponent
char opponent = (player == player_ch) ? computer_ch : player_ch;
board[row][col] = player; // Place the player counter
// Check all squares around this square for opponents counter
for(rowdelta = -1 ; rowdelta <= 1 ; ++rowdelta)
for(coldelta = -1; coldelta <= 1; ++coldelta)
{
// Don’t check off the board, or the current square
if((row == 0 && rowdelta == -1) || row + rowdelta >= SIZE ||
(col == 0 && coldelta == -1) || col + coldelta >= SIZE ||
(rowdelta == 0 && coldelta == 0))
continue;
// Now check the square
if(board[row + rowdelta][col + coldelta] == opponent)
{ // Found opponent so search in same direction for player counter
x = row + rowdelta; // Move to opponent
y = col + coldelta; // square
for(;;)
{
x += rowdelta; // Move to the
y += coldelta; // next square
if(board[x][y] == problem_ch) // If square is blank...
break; // ...give up
// If we find the player counter, go backward from here
// changing all the opponents counters to player
if(board[x][y] == player)
{
while(board[x -= rowdelta][y -= coldelta] == opponent) // Opponent?
board[x][y] = player; // Yes, change it
break; // We are done
}
}
}
}
}

understanding entab example code in k&r

I'm teaching myself C and working through K&R. I'm doing exercise 1-21:
Write a Program entab that replaces strings of blanks by the minimum number of tabs and blanks to acheive the same spacing. Use the same tab stops as for detab.
I was having trouble doing this exercise so I found a solution online but I do not understand it. Can someone explain how this code works?
#include<stdio.h>
#define TABINC 8
int main(void)
{
int nb,nt,pos,c;
nb = 0;
nt = 0;
for(pos=1;(c=getchar())!=EOF;++pos)
if( c == ' ')
{
if((pos % TABINC) != 0)
++nb;
else
{
nb = 0;
++nt;
}
}
else
{
for( ; nt > 0 ; --nt)
putchar('\t');
if( c == '\t')
nb = 0;
else
for( ; nb > 0; --nb)
putchar(' ');
putchar(c);
if(c == '\n')
pos = 0;
else if ( c == '\t')
pos = pos + ( TABINC - (pos -1) % TABINC) - 1;
}
return 0;
}
The code is to
put a tab ('\t') when a space () is encountered at a position that is a multiple of TABINC, i.e, the size of the tab.
when a tab is encountered, the number of spaces is reset. This is to prefer a tab to reach a tabstop
To illustrate:
- a space shown in *
- a tab is shown in
column: 1 2 3 4 5 6 7 8 9 10
input : * * * * h e l * * w
output: <tab>hel<tab>*w
In this example, when a space is encountered at every column position which is divisible by the TABINC, i.e 4 (in this case), a tab '\t' is inserted. Otherwise space.
Hope this will give you some idea.

K&R answer book exercise 1.21

Here is the question:
Write the program entab that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?
I did the exercise myself, and the book's answer has a different solution. I'm not understanding a mathematical formula that executes when a tab is read from the input stream. Here is the code:
#include <stdio.h>
#define TABINC 8
main()
{
int c, nb, nt, pos;
nb = 0;
nt = 0;
for (pos = 1; (c =getchar()) != EOF; ++pos)
if (c == ' '){
if (pos % TABINC != 0)
++nb;
else {
nb = 0;
++nt;
}
}
else {
for ( ; nt > 0; --nt)
putchar('\t');
if (c == '\t')
nb = 0;
else
for ( ; nb > 0; --nb)
putchar(' ');
putchar(c);
if ( c == '\n')
pos = 0;
else if (c == '\t')
pos = pos + (TABINC - (pos - 1) % TABINC) - 1;
}
}
The part I'm not understanding is the following:
else if (c == '\t')
pos = pos + (TABINC - (pos - 1) % TABINC) - 1;
I can see through debugging in visual studio that this construct brings the pos to the next tab stop when a tab occurs from the input stream. Is this correct?
What I really don't understand is how this formula works or how they came up with it. is this a common formula that occurs in programming? Is it useful? Does it have a name?
Edit: I do understand what the modulo operator does. I'm sorry I didn't specify that.
There is no specific name to this formula - it is a relatively straightforward way of applying math from the elementary school to everyday problems. Here is what's going on: '\t' character advances the pos by a number of positions ranging from one to TABINC, inclusive.
When pos is a multiple of TABINC, you jump the full TABINC
When pos is one below the next multiple of TABINC, you jump by one,
When pos is two below the next multiple of TABINC, you jump by two,
and so on - when pos is x, where 0 < x < TABINC, below the next multiple of TABINC, you jump x
Now the problem of calculating a jump is reduced to computing the difference between pos and the next multiple of TABINC. This can be done by computing a division remainder of the pos and TABINC, and subtracting that remainder from the TABINC. This is done with the % operator.
Since pos is one-based *, the first thing the formula does is making it zero-based for the purpose of calculating the remainder. Next, the formula computes the remainder, which is a mathematical way of saying "the number of positions above the last TABINC stop". Now all you need is subtracting that remainder from TABINC to get your result.
* The assignment pos=0 on discovering '\n' seemingly contradicts the assertion that pos is one-based. However, the loop header performs pos++ after each iteration, so the next iteration of the loop sees pos=1 on the next iteration.
It does not have a name or something like that.
In detail:
First of all, how much pos has to be increased depends on pos%TABINC,
ie. TABINC is 8, so if pos is a multiple from 8, add 8,
if pos%8 is 1 (like 9, 17...) then add 7,
if pos%8 is 2 (10, 18...) add 6 and so on.
Full list:
pos%8 -> number to add
0 -> 8
1 -> 7
2 -> 6
3 -> 5
4 -> 4
5 -> 3
6 -> 2
7 -> 1
That would be 8 - pos%8 or, more general TABINC - pos%TABINC
Important: A negative number modulo something in C is mathematically not correct
In C, for a,b >= 0: (-a)%b == -(a%b)
What is added in the code is (TABINC - (pos - 1) % TABINC) - 1
With some basic math and the fact above, this is
(TABINC - (pos - 1) % TABINC) - 1
= TABINC - ((pos - 1) % TABINC)) - 1
= TABINC - ((pos % TABINC) - 1) - 1
= TABINC + 1 - (pos % TABINC) - 1
= TABINC - (pos % TABINC)
which is the same as my short formula above, only more complex for no reason.

Resources