#include "maze.h" #include "utils.h" #include #include #include void validate_number_optarg(char *optarg, int c) { char *base_error = malloc((38 + 1) * sizeof(char)); sprintf(base_error, "Error: Invalid option argument for -%c.", c); if (!is_number(optarg)) { printf("%s It must be a number\n", base_error); exit(1); } if (atoi(optarg) < 1) { printf("%s It must be greater than 0\n", base_error); exit(1); } } 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); int full_maze_height = maze_height * 2 + 1; int full_maze_width = maze_width * 2 + 1; struct MazeSize maze_size = {.width = maze_width, .height = maze_height}; struct Maze maze = maze_create(maze_size, wall); struct Position start_pos = {.x = start_x, .y = start_y}; maze_excavate(maze, start_pos); maze_print(maze.grid, full_maze_width, full_maze_height); }