From 764070a86a7aa98480eaaff64dfba7e2f2943292 Mon Sep 17 00:00:00 2001 From: kartofen Date: Thu, 22 Dec 2022 22:43:44 +0200 Subject: refactor --- src/wfc.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/wfc.c (limited to 'src/wfc.c') diff --git a/src/wfc.c b/src/wfc.c new file mode 100644 index 0000000..e12d6de --- /dev/null +++ b/src/wfc.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include "typedef.h" +#include "wfc.h" +#include "tilemap.h" +#include "tiles.h" +#include "ppm.h" + +small_t DIMENTIONS; + +size_t width; +size_t height; + +size_t SEED; +size_t SCALE; + +void default_values() +{ + SEED = time(0); + width = 15; + height = 15; + SCALE = 9; +} + +int get_least_entropy_index() +{ + // array of indexes with the least entropy + size_t least_entpy[TILEMAP_CAP]; + size_t least_entpy_sz = 0; + + for(size_t i = 0; i < SHEIGHT; i++) + { + for (size_t j = 0; j < SWIDTH; j++) + { + size_t index = i * SWIDTH + j; + + if(least_entpy_sz == 0) { + least_entpy[least_entpy_sz++] = index; + continue; + } + + size_t b1s = count_entropy(index); + size_t l1s = count_entropy(least_entpy[least_entpy_sz-1]); + + if(b1s == l1s) { + if(least_entpy_sz >= TILEMAP_CAP) exit(69); + least_entpy[least_entpy_sz++] = index; + } else if(b1s < l1s) { + least_entpy[0] = index; + least_entpy_sz = 1; + } + } + } + + return least_entpy[rand() % least_entpy_sz]; + +} + +void collapse_this(int i) +{ + if(count_entropy(i) == 0) { + err("No possible tiles for this position: %d\n", i); + exit(EXIT_FAILURE); + } + + small_t possibilities[TILES]; + size_t psz = 0; + + for(size_t n = 0; n < TILES; n++) + if(is_set(i, n)) possibilities[psz++] = n; + + size_t t = possibilities[rand() % psz]; + collapse(i, t); // collapse a random tile + + // apply a bitmask, on tiles around the newly collapsed tile + if(i / SWIDTH != 0) // up + if(!(has_collapsed(i-SWIDTH))) + mask(i-SWIDTH, t, 0); + + if(i % SWIDTH != (SWIDTH - 1)) // right + if(!(has_collapsed(i+1))) + mask(i+1, t, 1); + + if(i % SWIDTH != 0) // left + if(!(has_collapsed(i-1))) + mask(i-1, t, 2); + + if(i / SWIDTH != (SHEIGHT - 1)) // down + if(!(has_collapsed(i+SWIDTH))) + mask(i+SWIDTH, t, 3); +} + +void wfc() +{ + for(int lei = get_least_entropy_index(); !has_collapsed(lei); lei = get_least_entropy_index()) + collapse_this(lei); +} + +void save_wfc() +{ + size_t img_wdt = TILE_WIDTH * SWIDTH; + size_t img_hgt = TILE_HEIGHT * SHEIGHT; + small_t *image = malloc(img_wdt * img_hgt * 3); + + for(size_t i = 0; i < SHEIGHT; i++) + { + for(size_t j = 0; j < SWIDTH; j++) + { + size_t t = get_collapsed_tile((i * SWIDTH) + j); + + for(size_t y = 0; y < TILE_HEIGHT; y++) + for(size_t x = 0; x < TILE_WIDTH; x++) + for(int k = 0; k < 3; k++) + image[((y+(i*TILE_HEIGHT))*img_wdt+ + (x+(j*TILE_WIDTH)))*3 + k] = + get_tile_pixel(t, x, y, k); + } + } + + + + char file_name[128] = {0}; + sprintf(file_name, "%s/file_%ld.ppm", PATH, SEED); + + save_as_ppm(file_name, image, img_wdt, img_hgt, SCALE); + info("Saved file with name: %s", file_name); + + free(image); +} + +void init_wfc() +{ + FILE *fp = fopen("files/tiles/tiles.dat", "rb"); + if(!fp) { + err("Could not open file: %s\n", "files/tiles/tiles.dat"); + exit(EXIT_FAILURE); + } + + fread(&DIMENTIONS, sizeof(DIMENTIONS), 1, fp); + + load_tiles(fp); + info("Tiles Loaded"); + + //load_rules(fp); + //info("Tile Rules Loaded"); + + fclose(fp); + + init_tilemap(width, height); + info("Tilemap Initialized"); +} + + +void deinit_wfc() +{ + free_tiles(); + destroy_tilemap(); +} -- cgit v1.2.3