aboutsummaryrefslogtreecommitdiff
path: root/mazerator.c
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2021-12-13 21:16:54 +0100
committerHampusM <hampus@hampusmat.com>2021-12-13 21:16:54 +0100
commitaf93edd8433634d82e855e9c9bcbca249a476977 (patch)
tree14577381b1bc101eb14080c13e624743c120a86e /mazerator.c
parent5afa8ec91fbbb8c20e2425d56d11cac8bd08c8a4 (diff)
refactor: clean code
Diffstat (limited to 'mazerator.c')
-rw-r--r--mazerator.c191
1 files changed, 18 insertions, 173 deletions
diff --git a/mazerator.c b/mazerator.c
index 46ac9fc..33c47ce 100644
--- a/mazerator.c
+++ b/mazerator.c
@@ -1,176 +1,12 @@
-#include "stack.h"
-#include <ctype.h>
+#include "maze.h"
+#include "utils.h"
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/**
- * Returns a position in the maze from coordinates y and x.
- *
- * This is achieved by concatenating the binary values of the two variables.
- *
- * For example:
- *
- * Y: 8 (0b00001000)
- * X: 15 (0b00001111)
- *
- * Will become:
- * 0b0000100000001111
- */
-int get_maze_pos(int posY, int posX)
-{
- return ((posY) << 8) | posX;
-}
-
-/**
- * Returns y and x coordinates from a position in the maze.
- */
-int get_maze_coords(int pos, int *y, int *x)
-{
- *y = pos >> 8;
- *x = pos & 255;
- return 1;
-}
-
-/**
- * Returns whether or not a string is a number.
- */
-int is_number(char *str)
-{
- size_t len = strlen(str);
- for (int c = 0; c < len; c++)
- {
- if (!isdigit(str[c]))
- return 0;
- }
- return 1;
-}
-
-/**
- * Returns a maze filled with walls.
- *
- * Arguments:
- * - height: The height of the new maze
- * - width: The width of the new maze
- * - wall: The wall to fill the new maze with
- */
-char ***create_maze(int height, int width, char *wall)
-{
- char ***maze;
-
- // Fill the maze with walls
- maze = malloc(height * sizeof(char **));
- for (int y = 0; y < height; y++)
- {
- maze[y] = malloc(width * sizeof(char *));
-
- for (int x = 0; x < width; x++)
- {
- maze[y][x] = wall;
- }
- }
-
- return maze;
-}
-
-/**
- * Excavates a maze.
- *
- * This is what creates the actual maze.
- *
- * Arguments:
- * - maze: The maze to excavate
- * - maze_height: The height of the maze
- * - maze_width: The width of the maze
- * - start_x: X coordinate to start on
- * - start_y Y coordinate to start on
- */
-void excavate_maze(char ***maze, int maze_height, int maze_width, int start_x, int start_y)
-{
- struct stack *path = create_stack(maze_width * maze_height);
-
- stack_push(path, get_maze_pos(start_y, start_x));
-
- int visited_pos_cnt = 0;
- while (1)
- {
- int pos = stack_peek(path);
- int posY, posX;
- get_maze_coords(pos, &posY, &posX);
-
- // Set the currently visited grid square to 1 indicating that it has been
- // visited and excavate the visual maze
- maze[posY * 2 + 1][posX * 2 + 1] = " ";
-
- // Find out available next positions to go to
- int neighbours[3];
- int neighbour_cnt = 0;
-
- if (posY != 0 && strcmp(maze[posY * 2 - 1][posX * 2 + 1], " ") != 0)
- {
- neighbours[neighbour_cnt] = get_maze_pos(posY - 1, posX);
- neighbour_cnt++;
- }
- if (posY != maze_height - 1 && strcmp(maze[(posY + 1) * 2 + 1][posX * 2 + 1], " ") != 0)
- {
- neighbours[neighbour_cnt] = get_maze_pos(posY + 1, posX);
- neighbour_cnt++;
- }
- if (posX != 0 && strcmp(maze[posY * 2 + 1][posX * 2 - 1], " ") != 0)
- {
- neighbours[neighbour_cnt] = get_maze_pos(posY, posX - 1);
- neighbour_cnt++;
- }
- if (posX != maze_width - 1 && strcmp(maze[posY * 2 + 1][(posX + 1) * 2 + 1], " ") != 0)
- {
- neighbours[neighbour_cnt] = get_maze_pos(posY, posX + 1);
- neighbour_cnt++;
- }
-
- if (neighbour_cnt == 0)
- {
- if (visited_pos_cnt == (maze_height * maze_width) - 1)
- {
- // The whole maze have been visited
- break;
- }
-
- // Go back a step
- stack_pop(path);
- continue;
- }
-
- visited_pos_cnt++;
-
- int next_pos = neighbours[rand() % neighbour_cnt];
-
- int next_pos_y, next_pos_x;
- get_maze_coords(next_pos, &next_pos_y, &next_pos_x);
-
- maze[posY * 2 - (posY - next_pos_y) + 1]
- [posX * 2 - (posX - next_pos_x) + 1] = " ";
-
- stack_push(path, next_pos);
- }
-}
-
-void print_maze(char ***maze, int height, int width)
-{
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- printf("%s", maze[y][x]);
- }
- printf("\n");
- }
-}
void validate_number_optarg(char *optarg, int c)
{
- char *base_error = malloc(39 * sizeof(char));
+ char *base_error = malloc((38 + 1) * sizeof(char));
sprintf(base_error, "Error: Invalid option argument for -%c.", c);
if (!is_number(optarg))
@@ -203,6 +39,13 @@ void validate_start_coords(int start_x, int start_y, int width, int height)
}
}
+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'},
@@ -273,9 +116,7 @@ int main(int argc, char *argv[])
if (seed == -1)
{
- FILE *f = fopen("/dev/urandom", "r");
- fread(&seed, sizeof(seed), 1, f);
- fclose(f);
+ get_seed(&seed);
}
srand(seed);
@@ -283,9 +124,13 @@ int main(int argc, char *argv[])
int full_maze_height = maze_height * 2 + 1;
int full_maze_width = maze_width * 2 + 1;
- char ***maze = create_maze(full_maze_height, full_maze_width, wall);
+ 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};
- excavate_maze(maze, maze_height, maze_width, start_x, start_y);
+ maze_excavate(maze, start_pos);
- print_maze(maze, full_maze_height, full_maze_width);
+ maze_print(maze.grid, full_maze_width, full_maze_height);
}