aboutsummaryrefslogtreecommitdiff
path: root/src/mazerator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mazerator.c')
-rw-r--r--src/mazerator.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/mazerator.c b/src/mazerator.c
new file mode 100644
index 0000000..33c47ce
--- /dev/null
+++ b/src/mazerator.c
@@ -0,0 +1,136 @@
+#include "maze.h"
+#include "utils.h"
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+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);
+}