lundi 29 novembre 2021

why my random maze generation program doesn't work randomly , while working well on debugging mode [duplicate]

I made a program which generates M by N maze randomly. I visit neighbor 'room' randomly by setting the parameter of srand() function as time(null) function.

But When I run the program, The maze is generated only two ways, either go straight to the end of the maze horizontally or vertically (as below).

enter image description here enter image description here

But What is more mysterious for me is, when I tried to debug to find the error, I found maze is generated randomly well on debugging mode where I run line by line by pushing f5 button. The result on debugging mode is below.

enter image description here

enter image description here

So I'm confused whether there is no logical error on my code or not.

I appreciate your help. My code is as below.

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>

typedef struct coord {
    int row, col; 
}coord;
typedef enum direction{down = 0, up, right, left, none};

void errorExit(const char* msg); 
char** arrAlloc(int height, int width);
void initialize_rooms(char** rooms, int height, int width);
void initialize_maps(char** maps, int height, int width);
void DfsMazeGeneration(coord current, int dir);
void check_adjacent_rooms(coord current, coord possible_neighbors[], int possible_dir[],  int* possible_num);
bool IsVisited(int next, int visited_dir[], int possible_num);
void break_wall(coord current, int dir);
void printMap(int row_size, int col_size); 

char** rooms; 
char** maps; 
coord size; 
int unvisited; 
bool end_flag = false; 
coord offsets[4] = { {1,0}, {-1,0}, {0,1}, {0,-1} }; // down, up, right, left order from current room
int main(void) {
    int N, M; // N: width, M: height  
    coord start_point = { 0, 0 }; 
    scanf("%d %d", &N, &M); 
    
    rooms = arrAlloc(M, N); 
    maps = arrAlloc(2 * M + 1, 2 * N + 1);
    unvisited = M * N; 
    size.row = M;
    size.col = N; 
     
    initialize_rooms(rooms, M, N);
    initialize_maps(maps, 2 * M + 1, 2 * N + 1); 
    
    DfsMazeGeneration(start_point, none);

    printMap(2 * M + 1, 2 * N + 1); 

}
void printMap(int row_size, int col_size) {
    for (int i = 0; i < row_size; i++) {
        for (int j = 0; j < col_size; j++) {
            printf("%c", maps[i][j]); 
        }
        printf("\n"); 
    }
}
void DfsMazeGeneration(coord current, int dir) {
    int row = current.row;
    int col = current.col; 
    int idx_for_visited = 0; // index for visited_dir 
    coord possible_neighbors[4]; 
    int possible_dir[4]; 
    int visited_dir[4]; 
    int possible_num = 0; 
    int next; 

    if (end_flag == true) return;
    else if (rooms[row][col] == true) return; 
    else if (rooms[row][col] == false){
        // debugging part: 
        // printf("(%d, %d)\n", row, col); 
        

        break_wall(current, dir);
        
        rooms[row][col] = true;
        unvisited--;
    }
    if (unvisited == 0) {
        end_flag = true;
        return; 
    }

    /* check adjacent rooms: check neighbor rooms whether it is valid room and unvisited room and return valid neighbor rooms as list */
    
    check_adjacent_rooms(current, possible_neighbors, possible_dir,  &possible_num);
    for (int i = 0; i < possible_num; i++) {
        do {
            srand(time(NULL)); 
            next = rand() % possible_num;

        }while (IsVisited(next, visited_dir, idx_for_visited)); 

        visited_dir[idx_for_visited++] = next; 
        DfsMazeGeneration(possible_neighbors[next], possible_dir[next]); 
        
        if (end_flag == true) return; 
    }
}
void break_wall(coord current, int dir) {
    /*
    from left: assign map[2i+1][2j] as ' '
    from right: assign map[2i+1][2j+2] as ' '
    from up: assign map[2i+2[[2j+1] as ' '
    from down: assign map[2i][2j+1] as ' ' 
    
    from none(only in start position): no operation 

    */

    // row, col index of current room on maps array 
    int row = 2 * current.row + 1;
    int col = 2 * current.col + 1;
    
    switch (dir) {
    case(left): maps[row][col + 1] = ' '; break;
    case(right): maps[row][col - 1] = ' '; break;
    case(up): maps[row + 1][col] = ' '; break;
    case(down): maps[row - 1][col] = ' '; break; 
    case(none): break;
    }
    





}


bool IsVisited(int next, int visited_dir[], int visited_so_far) {
    for (int i = 0; i < visited_so_far; i++) {
        if (visited_dir[i] == next)
            return true;
    }
    return false; // next is not included in list 'visited_dir'  
}
void check_adjacent_rooms(coord current, coord possible_neighbors[], int possible_dir[],  int* possible_num) {
    int row, col, idx = 0;
    coord neighbor; 
    for (int i = 0; i < 4; i++) {
        row = current.row + offsets[i].row;
        col = current.col + offsets[i].col;
        neighbor.row = row;
        neighbor.col = col; 
        if (row < 0 || row >= size.row || col < 0 || col >= size.col)
            continue; 
        if (rooms[row][col] == true) {
            continue; 
        }

        possible_neighbors[idx] = neighbor; 
        possible_dir[idx++] = i; 
        (*possible_num)++; 
    }
}
void initialize_rooms(char **rooms, int height, int width) {
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            rooms[i][j] = false; //rooms are unvisited; 
        }
    }
}
void initialize_maps(char** maps, int height, int width) {
    
    //initialize room part 
    for (int i = 1; i < height; i += 2) {
        for (int j = 1; j < width - 1; j += 2)
            maps[i][j] = ' '; 
    }

    //initialize edge part
    for (int i = 0; i < height; i += 2) {
        for (int j = 0; j < width; j += 2) {
            maps[i][j] = '+';
        }
    }

    //initialize vertical wall part 
    for (int i = 1; i < height; i += 2) {
        for (int j = 0; j < width; j += 2) {
            maps[i][j] = '|';
        }
    }

    //initialize horizontal wall part
    for (int i = 0; i < height; i += 2) {
        for (int j = 1; j < width; j += 2) {
            maps[i][j] = '-';
        }
    }
}

char** arrAlloc(int height, int width){
    char **arr = (char**)malloc(sizeof(char*) * height);
    if (arr == NULL) 
        errorExit("Memory Allocation Error.\n"); 

    for (int i = 0; i < height; i++) {
        arr[i] = (char*)malloc(sizeof(char) * width); 
        if (arr[i] == NULL)
            errorExit("Memory Allocation Error.\n"); 
    }
    return arr;
}



void errorExit(const char* msg) {
    printf("%s", msg);
    exit(1); 
}




Aucun commentaire:

Enregistrer un commentaire