static void maze_generate(struct maze* maze) { int total_cells = MAZE_WIDTH * MAZE_HEIGHT; int visited_cells; int available_neighbours; int x, y; int nx = 0; int ny = 0; struct coord_stack done_cells; coord_stack_init(&done_cells); x = rb->rand()%MAZE_WIDTH; y = rb->rand()%MAZE_HEIGHT; visited_cells = 1; while (visited_cells < total_cells){ available_neighbours = maze_pick_random_neighbour_cell_with_walls(maze, x, y, &nx, &ny); if(available_neighbours == 0){ /* pop from stack */ coord_stack_pop(&done_cells, &x, &y); } else { /* remove the wall */ maze_remove_wall(maze, x, y, nx, ny); /* save our position on the stack */ coord_stack_push(&done_cells, x, y); /* move to the next cell */ x=nx; y=ny; /* keep track of visited cells count */ visited_cells++; } } }
/* * Find a boundary between the created and inchoate portions of the maze. * Return 0 if the maze is now fully created. */ int maze_find_boundary(struct maze *mp, int *prevrow, int *prevcol, int *currow, int *curcol) { int d; int cr; int cc; int pr; int pc; int vi; int vi_lim; int vi_start; if (mp->lastvi == -1 || drandom() > mp->revisit) vi = drandom() * mp->vi; else vi = mp->lastvi; vi_lim = mp->vi; vi_start = vi; do { pr = mp->visited[vi].row; pc = mp->visited[vi].col; cr = -1; if (!maze_cell_visited(mp, pr - 1, pc)) { cr = pr - 1; cc = pc; } if (!maze_cell_visited(mp, pr + 1, pc) && (cr == -1 || drandom() < 0.5)) { cr = pr + 1; cc = pc; } if (!maze_cell_visited(mp, pr, pc - 1) && (cr == -1 || drandom() < 0.5)) { cr = pr; cc = pc - 1; } if (!maze_cell_visited(mp, pr, pc + 1) && (cr == -1 || drandom() < 0.5)) { cr = pr; cc = pc + 1; } if (cr != -1) { d = maze_get_cell_distance(mp, pr, pc); maze_remove_wall(mp, pr, pc, cr, cc); maze_visit_cell(mp, cr, cc, d + 1); *prevrow = pr; *prevcol = pc; *currow = cr; *curcol = cc; mp->lastvi = vi; return 1; } vi++; if (vi >= mp->vi) vi = 0; if (vi_lim != mp->vi) ABORT(); } while (vi != vi_start); return 0; /* Maze is now finished. */ }