Reorganize code into library for reuse
This commit is contained in:
188
lib/grid.c
Normal file
188
lib/grid.c
Normal 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");
|
||||
}
|
||||
Reference in New Issue
Block a user