#include "maze.h" #include "utils.h" #include #include #include void validate_number_optarg(char *optarg, int c) { unsigned int is_invalid = 0; size_t error_length = 40; char *error = malloc(error_length + 1); if (!is_number(optarg)) { is_invalid = 1; snprintf(error, error_length, "It must be a number"); } else if (atoi(optarg) < 1) { is_invalid = 1; snprintf(error, error_length, "It must be greater than 0"); } if (is_invalid == 1) { printf("Error: Invalid option argument for -%c. %s\n", c, error); free(error); exit(1); } free(error); } void validate_start_coords(int start_x, int start_y, int width, 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(1); } if (start_y > height) { printf(error_format, "y", "height"); exit(1); } } void get_seed(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[]) { int maze_width = 40; int maze_height = 20; int start_x = 0; int start_y = 0; char *wall = "█"; int seed = -1; int c; while ((c = getopt_long(argc, argv, "w:h:W:s:x:y:", options, NULL)) != -1) { switch (c) { case 'w': validate_number_optarg(optarg, c); maze_width = atoi(optarg); break; case 'h': validate_number_optarg(optarg, c); maze_height = atoi(optarg); break; case 'x': validate_number_optarg(optarg, c); start_x = atoi(optarg); break; case 'y': validate_number_optarg(optarg, c); start_y = atoi(optarg); break; case 'W': wall = optarg; break; case 's': validate_number_optarg(optarg, c); seed = atoi(optarg); 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: 0)\n" " -y, --start-y Y The y coordinate for the start position " "(Default: 0)\n" " -W, --wall WALL Single character used as maze walls " "(Default: '█')\n" " -s, --seed SEED The randomization seed used for maze " "generation (Any number)\n" " --help Displays usage information\n", argv[0]); exit(0); case '?': printf("\nTry '%s --help' for more information\n", argv[0]); exit(1); } } validate_start_coords(start_x, start_y, maze_width, maze_height); if (seed == -1) { get_seed(&seed); } srand(seed); Dimensions dimens = {.width = maze_width, .height = maze_height}; Maze maze = maze_create(dimens, wall); Position start_pos = {.x = start_x, .y = start_y}; maze_excavate(&maze, start_pos); maze_print(maze); maze_destroy(&maze); }