aboutsummaryrefslogtreecommitdiff
path: root/mazerator.c
diff options
context:
space:
mode:
Diffstat (limited to 'mazerator.c')
-rw-r--r--mazerator.c192
1 files changed, 87 insertions, 105 deletions
diff --git a/mazerator.c b/mazerator.c
index 9b2e434..f15c4ae 100644
--- a/mazerator.c
+++ b/mazerator.c
@@ -1,67 +1,26 @@
+#include "stack.h"
+#include <ctype.h>
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <ctype.h>
#include <string.h>
+#include <unistd.h>
// Error handling
-void err(int id){
- switch(id){
- case 0: printf("Error: Stack overflow\nBe kind and report this problem."); break;
- case 1: printf("Error: Stack underflow\nBe kind and report this problem."); break;
+void err(int id)
+{
+ switch (id)
+ {
+ case 0:
+ printf("Error: Stack overflow\nBe kind and report this problem.");
+ break;
+ case 1:
+ printf("Error: Stack underflow\nBe kind and report this problem.");
+ break;
}
exit(1);
}
-// The fundementals for the maze-generation algoritm
-// A stack data-structure
-struct stack
-{
- int max_size;
- int top;
- int *items;
-};
-
-// Create a new stack
-struct stack* new_stack(int capacity)
-{
- struct stack *pt = (struct stack*)malloc(sizeof(struct stack));
- pt->max_size = capacity;
- pt->top = -1;
- pt->items = (int*)malloc(sizeof(int) * capacity);
- return pt;
-}
-
-// Add a new item to a stack
-void stack_push(struct stack *pt, int x)
-{
- // Avoid a overflow by checking if the stack is full
- if (pt->top == pt->max_size - 1)
- err(0);
- // Add an element and increase the top index
- pt->items[++pt->top] = x;
-}
-
-// Get the topmost item of a stack
-int stack_peek(struct stack *pt)
-{
- // Check if the stack is empty
- if (pt->top == -1)
- err(1);
- return pt->items[pt->top];
-}
-
-// Remove the topmost item of a stack
-int stack_pop(struct stack *pt)
-{
- // Check for a stack underflow
- if (pt->top == -1)
- err(0);
- // Decrease the stack size by 1 and (optionally) return the popped element
- return pt->items[pt->top--];
-}
-
// Get a position in the maze from coordinates y and x
//
// This is achieved by concatenating the binary values of the two variables.
@@ -71,10 +30,7 @@ int stack_pop(struct stack *pt)
// X: 15 00001111
// Will become:
// 0000100000001111
-int get_maze_pos(int posY, int posX)
-{
- return ((posY) << 8) | posX;
-}
+int get_maze_pos(int posY, int posX) { return ((posY) << 8) | posX; }
// Get y and x coordinates from a position in the maze
//
@@ -91,46 +47,51 @@ int get_maze_coords(int pos, int *y, int *x)
// Find out if a string is a number by running it through
// isdigit() char-by-char
-int is_number(char * str)
+int is_number(char *str)
{
size_t len = strlen(str);
- for(int c = 0; c < len; c++){
- if(!isdigit(str[c]))
+ for (int c = 0; c < len; c++)
+ {
+ if (!isdigit(str[c]))
return 0;
}
return 1;
}
-// Where the magic happends
int main(int argc, char *argv[])
{
int maze_width = 40;
int maze_heigth = 20;
char *wall = "█";
- int seed;
+ int seed = 0;
static struct option options[] = {
/* NAME ARGUMENT FLAG SHORTNAME */
- {"width", required_argument, NULL, 'w'},
- {"heigth", required_argument, NULL, 'h'},
- {"wall", required_argument, NULL, 'W'},
- {"seed", required_argument, NULL, 's'},
- {"help", no_argument, NULL, 0},
- {NULL, 0, NULL, 0}
- };
-
+ {"width", required_argument, NULL, 'w'},
+ {"heigth", required_argument, NULL, 'h'},
+ {"wall", required_argument, NULL, 'W'},
+ {"seed", required_argument, NULL, 's'},
+ {"help", no_argument, NULL, 0},
+ {NULL, 0, NULL, 0}};
+
int c;
- while((c = getopt_long(argc, argv, "w:h:W:s:", options, NULL)) != -1) {
- switch(c){
+ while ((c = getopt_long(argc, argv, "w:h:W:s:", options, NULL)) != -1)
+ {
+ switch (c)
+ {
case 'w':
case 'h':
// Set heigth or width
- if(is_number(optarg) && atoi(optarg) >= 1 && atoi(optarg) <= 255)
- switch(c){
- case 'h': maze_heigth = atoi(optarg);
- case 'w': maze_width = atoi(optarg);
+ if (is_number(optarg) && atoi(optarg) >= 1 && atoi(optarg) <= 255)
+ switch (c)
+ {
+ case 'h':
+ maze_heigth = atoi(optarg);
+ case 'w':
+ maze_width = atoi(optarg);
}
- else{
+ else
+ {
printf("Invalid option argument for -%c!\n", c);
exit(1);
}
@@ -141,17 +102,20 @@ int main(int argc, char *argv[])
break;
case 's':
// Set the seed
- if(is_number(optarg)){
+ if (is_number(optarg))
+ {
seed = atoi(optarg);
break;
}
- else{
+ else
+ {
printf("Invalid option argument for -s/--seed!\n");
exit(1);
}
case 0:
// Help
- printf("Usage: mazerator [--help] [-W wall] [-s seed] [-w width] [-h heigth]\n\n\
+ printf(
+ "Usage: mazerator [--help] [-W wall] [-s seed] [-w width] [-h heigth]\n\n\
OPTIONS\n\
--width -w The width of the maze. (1-255). Default: 40\n\
--heigth -h The heigth of the maze. (1-255). Default: 20\n\
@@ -165,75 +129,92 @@ OPTIONS\n\
exit(1);
}
}
-
+
int maze[maze_heigth][maze_width];
char *maze_visual[maze_heigth * 2 + 1][maze_width * 2 + 1];
struct stack *path = new_stack(maze_width * maze_heigth);
// Prepares seed value for randr()
// Get's a seed from /dev/urandom if not already set
- if(seed == 0){
+ if (seed == 0)
+ {
+ printf("What");
FILE *f = fopen("/dev/urandom", "r");
fread(&seed, sizeof(seed), 1, f);
fclose(f);
}
srand(seed);
-
+
// Prepares the maze grids
- // Fills the maze with zeroes indicating that none of the grid squares have been visited
+ // Fills the maze with zeroes indicating that none of the grid squares have
+ // been visited
//
// Fills the visual maze with walls
- for(int y = 0; y < sizeof(maze) / sizeof(maze[0]); y++){
- for(int x = 0; x < sizeof(maze[0]) / sizeof(maze[0][0]); x++){
+ for (int y = 0; y < sizeof(maze) / sizeof(maze[0]); y++)
+ {
+ for (int x = 0; x < sizeof(maze[0]) / sizeof(maze[0][0]); x++)
+ {
maze[y][x] = 0;
}
}
- for(int y = 0; y < sizeof(maze_visual) / sizeof(maze_visual[0]); y++){
- for(int x = 0; x < sizeof(maze_visual[0]) / sizeof(maze_visual[0][0]); x++){
+ for (int y = 0; y < sizeof(maze_visual) / sizeof(maze_visual[0]); y++)
+ {
+ for (int x = 0; x < sizeof(maze_visual[0]) / sizeof(maze_visual[0][0]);
+ x++)
+ {
maze_visual[y][x] = wall;
}
}
-
+
// Set the start value (0, 0) and begin the algoritm loop
stack_push(path, 0);
int cnt = 0;
- while(1){
+ 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
+
+ // Set the currently visited grid square to 1 indicating that it has been
+ // visited and excavate the visual maze
maze[posY][posX] = 1;
maze_visual[posY * 2 + 1][posX * 2 + 1] = " ";
// Find out available next positions to go to
int neighbours[3];
int i = 0;
- if(posY != 0 && maze[posY - 1][posX] == 0){
+ if (posY != 0 && maze[posY - 1][posX] == 0)
+ {
neighbours[i] = get_maze_pos(posY - 1, posX);
i++;
-
}
- if(posY != maze_heigth - 1 && maze[posY + 1][posX] == 0){
+ if (posY != maze_heigth - 1 && maze[posY + 1][posX] == 0)
+ {
neighbours[i] = get_maze_pos(posY + 1, posX);
i++;
}
- if(posX != 0 && maze[posY][posX - 1] == 0){
+ if (posX != 0 && maze[posY][posX - 1] == 0)
+ {
neighbours[i] = get_maze_pos(posY, posX - 1);
i++;
}
- if(posX != maze_width - 1 && maze[posY][posX + 1] == 0){
+ if (posX != maze_width - 1 && maze[posY][posX + 1] == 0)
+ {
neighbours[i] = get_maze_pos(posY, posX + 1);
i++;
}
- switch(i){
+ switch (i)
+ {
case 0:
// No available next positions
- if(cnt == (maze_heigth * maze_width) - 1){
- for(int y = 0; y < sizeof(maze_visual) / sizeof(maze_visual[0]); y++){
- for(int x = 0; x < sizeof(maze_visual[0]) / sizeof(maze_visual[0][0]); x++){
+ if (cnt == (maze_heigth * maze_width) - 1)
+ {
+ for (int y = 0; y < sizeof(maze_visual) / sizeof(maze_visual[0]); y++)
+ {
+ for (int x = 0;
+ x < sizeof(maze_visual[0]) / sizeof(maze_visual[0][0]); x++)
+ {
printf("%s", maze_visual[y][x]);
}
printf("\n");
@@ -249,7 +230,8 @@ OPTIONS\n\
int next = neighbours[rand() % i];
int next_y, next_x;
get_maze_coords(next, &next_y, &next_x);
- maze_visual[posY * 2 - (posY - next_y) + 1][posX * 2 - (posX - next_x) + 1] = " ";
+ maze_visual[posY * 2 - (posY - next_y) + 1]
+ [posX * 2 - (posX - next_x) + 1] = " ";
stack_push(path, next);
}
}