Reorganize code into library for reuse

This commit is contained in:
2021-05-08 15:58:59 -04:00
parent d1f144aca7
commit aa4d8efdd2
20 changed files with 140 additions and 75 deletions

188
lib/grid.c Normal file
View File

@@ -0,0 +1,188 @@
#include <stdlib.h>
#include "grid.h"
#define MAX_EDGE_WEIGHT 100
#define TOP_LEFT_CORNER "\xe2\x94\x8f"
#define TOP_RIGHT_CORNER "\xe2\x94\x93"
#define BOTTOM_LEFT_CORNER "\xe2\x94\x97"
#define BOTTOM_RIGHT_CORNER "\xe2\x94\x9b"
#define HORIZONTAL_BAR "\xe2\x94\x81"
#define VERTICAL_BAR "\xe2\x94\x83"
#define TOP_TEE "\xe2\x94\xb3"
#define BOTTOM_TEE "\xe2\x94\xbb"
#define LEFT_TEE "\xe2\x94\xa3"
#define RIGHT_TEE "\xe2\x94\xab"
#define CROSS "\xe2\x95\x8b"
#define VERTICAL_HALF_BOTTOM "\xe2\x95\xbb"
#define VERTICAL_HALF_TOP "\xe2\x95\xb9"
#define HORIZONTAL_HALF_LEFT "\xe2\x95\xb8"
#define HORIZONTAL_HALF_RIGHT "\xe2\x95\xba"
mazegrid_t mazegrid_new(size_t width, size_t height) {
mazeedges_t** grid = calloc(height, sizeof(mazeedges_t*));
for (size_t i = 0; i < height; i++) {
grid[i] = calloc(width, sizeof(mazeedges_t));
for (size_t j = 0; j < width; j++) {
grid[i][j].up = 0;
grid[i][j].right = 0;
}
}
mazegrid_t result = { .width = width, .height = height, .grid = grid };
return result;
}
void mazegrid_free(mazegrid_t* g) {
for (size_t i = 0; i < g->height; i++) {
free(g->grid[i]);
}
free(g->grid);
g->width = g->height = 0;
}
int mazegrid_set_edge(mazegrid_t* g, size_t x, size_t y, mazeedge_dir_t dir, edgeweight_t wt) {
if ((x >= g->width) || (y >= g->height)) return 0;
if ((x == 0) && (dir == EDGE_LEFT)) return 0;
if ((y == 0) && (dir == EDGE_DOWN)) return 0;
if ((x == g->width - 1) && (dir == EDGE_RIGHT)) return 0;
if ((y == g->height - 1) && (dir == EDGE_UP)) return 0;
if (dir == EDGE_LEFT) return mazegrid_set_edge(g, x - 1, y, EDGE_RIGHT, wt);
if (dir == EDGE_DOWN) return mazegrid_set_edge(g, x, y - 1, EDGE_UP, wt);
if (dir == EDGE_RIGHT) { g->grid[y][x].right = wt; return 1; }
g->grid[y][x].up = wt; return 1;
}
edgeweight_t mazegrid_get_edge(mazegrid_t const* g, size_t x, size_t y, mazeedge_dir_t dir) {
if ((x >= g->width) || (y >= g->height)) return 0;
if ((x == 0) && (dir == EDGE_LEFT)) return 0;
if ((y == 0) && (dir == EDGE_DOWN)) return 0;
if ((x == g->width - 1) && (dir == EDGE_RIGHT)) return 0;
if ((y == g->height - 1) && (dir == EDGE_UP)) return 0;
if (dir == EDGE_LEFT) return mazegrid_get_edge(g, x - 1, y, EDGE_RIGHT);
if (dir == EDGE_DOWN) return mazegrid_get_edge(g, x, y - 1, EDGE_UP);
if (dir == EDGE_RIGHT) return g->grid[y][x].right;
else return g->grid[y][x].up;
}
void mazegrid_randomize(mazegrid_t* g) {
for (size_t i = 0; i < g->height; i++) {
for (size_t j = 0; j < g->width; j++) {
if (i < g->height - 1) g->grid[i][j].up = (edgeweight_t)(random()%MAX_EDGE_WEIGHT);
if (j < g->width - 1) g->grid[i][j].right = (edgeweight_t)(random()%MAX_EDGE_WEIGHT);
}
}
}
void mazegrid_uniform(mazegrid_t* g) {
for (size_t i = 0; i < g->height; i++) {
for (size_t j = 0; j < g->width; j++) {
if (i < g->height - 1) g->grid[i][j].up = (int)(255.0 - (i - g->height / 2) * (i - g->height / 2) * (255.0 * 4 / (g->height * g->height)));
if (j < g->width - 1) g->grid[i][j].right = (int)(255.0 - (j - g->width / 2) * (j - g->width / 2) * (255.0 * 4 / (g->width * g->width)));
}
}
}
void mazegrid_print(mazegrid_t const* g, FILE * f) {
fprintf(f, TOP_LEFT_CORNER);
for (size_t i = 0; i < g->width; i++) {
fprintf(f, HORIZONTAL_BAR);
if (i == g->width - 1) fprintf(f, HORIZONTAL_HALF_LEFT);
else if (mazegrid_get_edge(g, i, g->height - 1, EDGE_RIGHT)) fprintf(f, HORIZONTAL_BAR);
else fprintf(f, TOP_TEE);
}
fprintf(f, "\n");
size_t row = g->height - 1;
while (1) {
if (row > 0) fprintf(f, VERTICAL_BAR);
else fprintf(f, " ");
for (size_t col = 0; col < g->width; col++) {
if ((row == g->height - 1) && (col == g->width - 1)) fprintf(f, " ");
else if (col == g->width - 1) fprintf(f, " " VERTICAL_BAR);
else if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) fprintf(f, " ");
else fprintf(f, " " VERTICAL_BAR);
}
fprintf(f, "\n");
if (row == 0) break;
row--;
if (mazegrid_get_edge(g, 0, row, EDGE_UP)) fprintf(f, VERTICAL_BAR);
else if (row > 0) fprintf(f, LEFT_TEE);
else fprintf(f, BOTTOM_LEFT_CORNER);
for (size_t col = 0; col < g->width - 1; col++) {
if (mazegrid_get_edge(g, col, row, EDGE_UP)) fprintf(f, " ");
else fprintf(f, HORIZONTAL_BAR);
if (mazegrid_get_edge(g, col, row, EDGE_UP)) {
if (mazegrid_get_edge(g, col, row + 1, EDGE_RIGHT)) {
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) {
fprintf(f, VERTICAL_HALF_BOTTOM);
} else {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, HORIZONTAL_HALF_RIGHT);
} else fprintf(f, TOP_LEFT_CORNER);
}
} else {
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, VERTICAL_HALF_TOP);
} else fprintf(f, VERTICAL_BAR);
} else {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, BOTTOM_LEFT_CORNER);
} else fprintf(f, LEFT_TEE);
}
}
} else {
if (mazegrid_get_edge(g, col, row + 1, EDGE_RIGHT)) {
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, HORIZONTAL_HALF_LEFT);
} else fprintf(f, TOP_RIGHT_CORNER);
} else {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, HORIZONTAL_BAR);
} else fprintf(f, TOP_TEE);
}
} else {
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, BOTTOM_RIGHT_CORNER);
} else fprintf(f, RIGHT_TEE);
} else {
if (mazegrid_get_edge(g, col, row, EDGE_RIGHT)) {
fprintf(f, BOTTOM_TEE);
} else fprintf(f, CROSS);
}
}
}
/*
if (mazegrid_get_edge(g, col, row, EDGE_UP)) {
fprintf(f, " ");
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) fprintf(f, VERTICAL_BAR);
else {
fprintf(f, TOP_LEFT_CORNER);
}
}
else {
fprintf(f, HORIZONTAL_BAR);
if (mazegrid_get_edge(g, col + 1, row, EDGE_UP)) fprintf(f, RIGHT_TEE);
else fprintf(f, HORIZONTAL_BAR);
}
*/
}
if (mazegrid_get_edge(g, g->width - 1, row, EDGE_UP)) fprintf(f, " " VERTICAL_BAR);
else {
fprintf(f, HORIZONTAL_BAR);
if (row + 2 == g->height) fprintf(f, TOP_RIGHT_CORNER);
else fprintf(f, RIGHT_TEE);
}
fprintf(f, "\n");
}
fprintf(f, HORIZONTAL_HALF_RIGHT);
for (size_t i = 0; i < g->width; i++) {
fprintf(f, HORIZONTAL_BAR);
if (mazegrid_get_edge(g, i, 0, EDGE_RIGHT)) fprintf(f, HORIZONTAL_BAR);
else if (i == g->width - 1) fprintf(f, BOTTOM_RIGHT_CORNER);
else fprintf(f, BOTTOM_TEE);
}
fprintf(f, "\n");
}