diff options
| author | kartofen <mladenovnasko0@gmail.com> | 2022-12-22 22:43:44 +0200 | 
|---|---|---|
| committer | kartofen <mladenovnasko0@gmail.com> | 2022-12-22 22:43:44 +0200 | 
| commit | 764070a86a7aa98480eaaff64dfba7e2f2943292 (patch) | |
| tree | 830589ac702d540bfd76cfb0e5faa5e8988432b0 /src/wfc.c | |
| parent | 4c9fafc4c126af2466dc6c56b9c952f901a1c726 (diff) | |
refactor
Diffstat (limited to 'src/wfc.c')
| -rw-r--r-- | src/wfc.c | 159 | 
1 files changed, 159 insertions, 0 deletions
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 <stdio.h> +#include <stdlib.h> +#include <time.h> +#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(); +}  | 
