#include "maze.h" #include "grid.h" #include "position.h" #include "utils.h" #include #include #include void optarg_error(char arg, char *error) { printf("Error: Invalid option argument for -%c. %s\n", arg, error); exit(EXIT_FAILURE); } void validate_start_coords(unsigned int start_x, unsigned int start_y, unsigned int width, unsigned int height) { char *error_format = "Error: The %s start coordinate is not allowed to be higher than the maze's %s\n"; if (start_x > width) { printf(error_format, "x", "width"); exit(EXIT_FAILURE); } if (start_y > height) { printf(error_format, "y", "height"); exit(EXIT_FAILURE); } } void get_seed(unsigned int *seed_dst) { FILE *urandom = fopen("/dev/urandom", "r"); fread(seed_dst, sizeof(*seed_dst), 1, urandom); fclose(urandom); } const struct option options[] = {{"width", required_argument, NULL, 'w'}, {"heigth", required_argument, NULL, 'h'}, {"wall", required_argument, NULL, 'W'}, {"seed", required_argument, NULL, 's'}, {"start-x", required_argument, NULL, 'x'}, {"start-y", required_argument, NULL, 'y'}, {"help", no_argument, NULL, 0}, {NULL, 0, NULL, 0}}; int main(int argc, char *argv[]) { unsigned int maze_width = 40U; unsigned int maze_height = 20U; unsigned int *start_x = NULL; unsigned int *start_y = NULL; unsigned int *seed = NULL; char *wall = "█"; int arg; while ((arg = getopt_long(argc, argv, "w:h:W:s:x:y:", options, NULL)) != -1) { char *err = NULL; switch (arg) { case 'w': maze_width = str_to_uint(optarg, &err); if (err != NULL) optarg_error(arg, err); if (maze_width == 0) optarg_error(arg, "It should not be 0"); break; case 'h': maze_height = str_to_uint(optarg, &err); if (err != NULL) optarg_error(arg, err); if (maze_height == 0) optarg_error(arg, "It should not be 0"); break; case 'x': start_x = malloc_s(sizeof(unsigned int *)); *start_x = str_to_uint(optarg, &err); if (err != NULL) optarg_error(arg, err); break; case 'y': start_y = malloc_s(sizeof(unsigned int *)); *start_y = str_to_uint(optarg, &err); if (err != NULL) optarg_error(arg, err); break; case 'W': wall = optarg; break; case 's': seed = malloc_s(sizeof(unsigned int *)); *seed = str_to_uint(optarg, &err); if (err != NULL) optarg_error(arg, err); if (*seed == 0) optarg_error(arg, "It should not be 0"); break; case 0: printf("Usage: %s [OPTION]...\n\n" "Options:\n" " -w, --width WIDTH The width of the maze (Default: 40)\n" " -h, --heigth HEIGHT The heigth of the maze (Default: 20)\n" " -x, --start-x X The x coordinate for the start position " "(Default: random)\n" " -y, --start-y Y The y coordinate for the start position " "(Default: random)\n" " -W, --wall WALL Single character used as maze walls " "(Default: '█')\n" " -s, --seed SEED The randomization seed used for maze " "generation\n" " --help Displays usage information\n", argv[0]); exit(0); case '?': printf("\nTry '%s --help' for more information\n", argv[0]); exit(EXIT_FAILURE); } } if (seed == NULL) { seed = malloc_s(sizeof(unsigned int *)); get_seed(seed); } srand(*seed); free(seed); if (start_x == NULL) { start_x = malloc_s(sizeof(unsigned int *)); *start_x = rand() % maze_width; } if (start_y == NULL) { start_y = malloc_s(sizeof(unsigned int *)); *start_y = rand() % maze_height; } validate_start_coords(*start_x, *start_y, maze_width, maze_height); Position start_pos = position_create(*start_x * 2U + 1U, *start_y * 2U + 1U); Grid grid = grid_create(maze_width * 2U + 1U, maze_height * 2U + 1U, wall); grid_to_maze(grid, start_pos); grid_print(grid); grid_destroy(grid); free(start_x); free(start_y); }