diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen_tiles.c | 3 | ||||
-rw-r--r-- | src/main.c | 151 | ||||
-rw-r--r-- | src/ppm.c | 1 | ||||
-rw-r--r-- | src/ppm.h | 3 | ||||
-rw-r--r-- | src/tilemap.c | 93 | ||||
-rw-r--r-- | src/tilemap.h | 17 | ||||
-rw-r--r-- | src/tiles.c | 20 | ||||
-rw-r--r-- | src/tiles.h | 6 | ||||
-rw-r--r-- | src/typedef.h | 12 |
9 files changed, 189 insertions, 117 deletions
diff --git a/src/gen_tiles.c b/src/gen_tiles.c index fbfe378..e70990e 100644 --- a/src/gen_tiles.c +++ b/src/gen_tiles.c @@ -2,9 +2,10 @@ #include <stdlib.h> #include <string.h> #include <sys/stat.h> +#include "typedef.h" #include "ppm.h" -#define TILES 5 +#define TILES 2 #define TILE_WIDTH 3 #define TILE_HEIGHT 3 #define TILE_SZ ((TILE_WIDTH) * (TILE_HEIGHT)) @@ -2,88 +2,38 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include "tiles.h" +#include "typedef.h" #include "ppm.h" +#include "tiles.h" +#include "tilemap.h" -#define TILES_CAP 63 size_t TILES; + size_t TILE_WIDTH; size_t TILE_HEIGHT; -small_t *(tiles[TILES_CAP]) = {0}; - -// each bit is if the tile has a connections or not -// from most signifact to least it is up, right, left, down -small_t tile_connections[TILES_CAP]; - -// 0 up 1 right -// 2 left 3 down -// each bit of the numbers is for every tiles -// if the tile is a possibility -// least significant bit is tile index 0 -size_t tile_masks[TILES_CAP][4] = {0}; - -#define WIDTH_SCALER 30 -#define HEIGHT_SCALER 30 - -size_t tiles_board[WIDTH_SCALER * HEIGHT_SCALER] = {0}; - -void generate_tile_masks() -{ - size_t wt_con[4] = {0}; - size_t no_con[4] = {0}; - - for(int n = 0; n < 4; n++) - { - for(size_t i = 0; i < TILES; i++) - wt_con[n] |= ((tile_connections[i] >> n) & 1) << i; - - no_con[n] = (~wt_con[n]) & ((1 << TILES) - 1); - } - - for(size_t i = 0; i < TILES; i++) - { - for(int n = 0; n < 4; n++) - { - if((tile_connections[i] >> (3-n)) & 1) - tile_masks[i][n] = wt_con[n]; - else tile_masks[i][n] = no_con[n]; - } - } -} - -size_t count_1s(int v) -{ - if(((v >> TILES) & 1) == 1) return TILES+1; - - v &= (1 << TILES) - 1; - - size_t c = 0; - for (c = 0; v; v >>= 1) - c += v & 1; - - return c; -} +size_t SWIDTH = 10; +size_t SHEIGHT = 10; int get_least_entropy_index() { // array of indexes with the least entropy - int least_entpy[WIDTH_SCALER * HEIGHT_SCALER]; + int least_entpy[TILEMAP_CAP]; size_t least_entpy_sz = 0; - for(int i = 0; i < HEIGHT_SCALER; i++) + for(size_t i = 0; i < SHEIGHT; i++) { - for (int j = 0; j < WIDTH_SCALER; j++) + for (size_t j = 0; j < SWIDTH; j++) { - int index = i * WIDTH_SCALER + j; + size_t index = i * SWIDTH + j; if(least_entpy_sz == 0) { least_entpy[least_entpy_sz++] = index; continue; } - int b1s = count_1s(tiles_board[index]); - int l1s = count_1s(tiles_board[least_entpy[least_entpy_sz-1]]); + size_t b1s = count_entropy(index); + size_t l1s = count_entropy(least_entpy[least_entpy_sz-1]); if(b1s == l1s) { least_entpy[least_entpy_sz++] = index; @@ -98,11 +48,11 @@ int get_least_entropy_index() } -void set_index(int i) +void collapse_this(int i) { int n = 0; - if(count_1s(tiles_board[i]) == 0) { + if(count_entropy(i) == 0) { fprintf(stderr, "ERROR: No possible tiles for this position: %d\n", i); exit(EXIT_FAILURE); } @@ -110,80 +60,71 @@ void set_index(int i) // this bad do { n = rand() % TILES; - if(((tiles_board[i] >> n) & 1) != 1) + if(!(is_set(i, n))) continue; - tiles_board[i] = 0; - tiles_board[i] |= (1 << n); - tiles_board[i] |= (1 << TILES); - } while(((tiles_board[i] >> TILES) & 1) != 1); + collapse(i, n); + } while(!(has_collapsed(i))); - if(i / WIDTH_SCALER != 0) // up - if(count_1s(tiles_board[i-WIDTH_SCALER]) != (TILES + 1)) - tiles_board[i-WIDTH_SCALER] &= tile_masks[n][0]; + if(i / SWIDTH != 0) // up + if(!(has_collapsed(i-SWIDTH))) + mask(i-SWIDTH, n, 0); - if(i % WIDTH_SCALER != (WIDTH_SCALER - 1)) // right - if(count_1s(tiles_board[i+1]) != (TILES + 1)) - tiles_board[i+1] &= tile_masks[n][1]; + if(i % SWIDTH != (SWIDTH - 1)) // right + if(!(has_collapsed(i+1))) + mask(i+1, n, 1); - if(i % WIDTH_SCALER != 0) // left - if(count_1s(tiles_board[i-1]) != (TILES + 1)) - tiles_board[i-1] &= tile_masks[n][2]; + if(i % SWIDTH != 0) // left + if(!(has_collapsed(i-1))) + mask(i-1, n, 2); - if(i / WIDTH_SCALER != (HEIGHT_SCALER - 1)) // down - if(count_1s(tiles_board[i+WIDTH_SCALER]) != (TILES + 1)) - tiles_board[i+WIDTH_SCALER] &= tile_masks[n][3]; + if(i / SWIDTH != (SHEIGHT - 1)) // down + if(!(has_collapsed(i+SWIDTH))) + mask(i+SWIDTH, n, 3); } int main(void) { - TILES = calc_tiles(); + calc_tiles(); if(TILES > TILES_CAP) { printf("ERROR: Too many tiles: %ld\n", TILES); exit(EXIT_FAILURE); } - time_t seed = time(0); + time_t seed = 420; srand(seed); printf("The Seed is %ld\n", seed); - load_connections(); - generate_tile_masks(); - - // init tiles board - for(int i = 0; i < WIDTH_SCALER * HEIGHT_SCALER; i++) - tiles_board[i] = (1 << TILES) - 1; + generate_tile_masks(load_tile_connections()); + init_tilemap(); while(1) { int lei; lei = get_least_entropy_index(); - if(count_1s(tiles_board[lei]) == TILES+1) + if(has_collapsed(lei)) break; // every index is set else - set_index(lei); + collapse_this(lei); } load_tiles(); - size_t img_wdt = TILE_WIDTH * WIDTH_SCALER; - size_t img_hgt = TILE_HEIGHT * HEIGHT_SCALER; - small_t *image = malloc(img_wdt * img_hgt); + size_t img_wdt = TILE_WIDTH * SWIDTH; + size_t img_hgt = TILE_HEIGHT * SHEIGHT; + small_t *image = malloc(img_wdt * img_hgt * sizeof(small_t)); memset(image, 0, img_wdt * img_hgt); - for(size_t i = 0; i < HEIGHT_SCALER; i++) + for(size_t i = 0; i < SHEIGHT; i++) { - for(size_t j = 0; j < WIDTH_SCALER; j++) + for(size_t j = 0; j < SWIDTH; j++) { - size_t t; - for(t = 0; t < TILES; t++) - if(((tiles_board[i * WIDTH_SCALER + j] >> t) & 1) == 1) break; - - for(size_t y = 0; y < TILE_HEIGHT; y++) { - for(size_t x = 0; x < TILE_WIDTH; x++) { - image[(y+(i*TILE_HEIGHT)) * img_wdt + (x+(j*TILE_WIDTH))] = tiles[t][y * TILE_WIDTH + x]; - } - } + size_t t = get_collapsed_tile(i * SWIDTH + j); + if(t == TILES) exit(-124); + + for(size_t y = 0; y < TILE_HEIGHT; y++) + for(size_t x = 0; x < TILE_WIDTH; x++) + image[(y+(i*TILE_HEIGHT)) * img_wdt + (x+(j*TILE_WIDTH))] = get_tile_pixel(t, x, y); } } @@ -1,6 +1,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "typedef.h" #include "ppm.h" void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler) @@ -1,9 +1,6 @@ #ifndef PPM_H #define PPM_H -#include <stdint.h> -typedef uint8_t small_t; - void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler); small_t *load_from_ppm(char *file_path, size_t *width, size_t *height); diff --git a/src/tilemap.c b/src/tilemap.c new file mode 100644 index 0000000..70d534f --- /dev/null +++ b/src/tilemap.c @@ -0,0 +1,93 @@ +#include "typedef.h" +#include "tilemap.h" + +extern size_t TILES; +extern size_t SWIDTH; +extern size_t SHEIGHT; + +big_t tilemap[TILEMAP_CAP]; + +// 0 up 1 right +// 2 left 3 down +// each bit of the numbers is for every tiles +// if the tile is a possibility +// least significant bit is tile index 0 +big_t tile_masks[TILES_CAP][4]; + +void set(int i, int n) +{ + tilemap[i] |= (1 << n); +} + +int is_set(int i, int n) +{ + return (tilemap[i] >> n) & 1; +} + +void init_tilemap() +{ + for(size_t i = 0; i < SWIDTH * SHEIGHT; i++) + for(size_t n = 0; n < TILES; n++) + set(i, n); +} + +size_t count_entropy(int i) +{ + if(has_collapsed(i)) return TILES+1; + + size_t c = 0; + for (size_t j = 0; j < TILES; j++) + c += is_set(i, j); + + return c; +} + +void collapse(int i, int n) +{ + tilemap[i] = 0; + set(i, n); + set(i, TILES); +} + +int has_collapsed(int i) +{ + return is_set(i, TILES); +} + +int get_collapsed_tile(int i) +{ + for(size_t t = 0; t < TILES; t++) + if(is_set(i, t)) return t; + + return TILES; +} + + +void mask(int i, int m, int r) +{ + tilemap[i] &= tile_masks[m][r]; +} + +void generate_tile_masks(small_t* tile_connections) +{ + size_t wt_con[4] = {0}; + size_t no_con[4] = {0}; + + for(int n = 0; n < 4; n++) + { + for(size_t i = 0; i < TILES; i++) + wt_con[n] |= ((tile_connections[i] >> n) & 1) << i; + + no_con[n] = (~wt_con[n]) & ((1 << TILES) - 1); + } + + for(size_t i = 0; i < TILES; i++) + { + for(int n = 0; n < 4; n++) + { + if((tile_connections[i] >> (3-n)) & 1) + tile_masks[i][n] = wt_con[n]; + else tile_masks[i][n] = no_con[n]; + } + } +} diff --git a/src/tilemap.h b/src/tilemap.h new file mode 100644 index 0000000..e945f06 --- /dev/null +++ b/src/tilemap.h @@ -0,0 +1,17 @@ +#ifndef TILEMAP_H +#define TILEMAP_H + +void set(int i, int n); +int is_set(int i, int n); + +void mask(int i, int m, int r); +void generate_tile_masks(small_t* tile_connections); + +void init_tilemap(); + +size_t count_entropy(int i); +void collapse(int i, int n); +int has_collapsed(int i); +int get_collapsed_tile(int i); + +#endif diff --git a/src/tiles.c b/src/tiles.c index 2432736..6b7a39b 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -1,14 +1,16 @@ #include <stdio.h> #include <stdlib.h> +#include "typedef.h" +#include "tiles.h" #include "ppm.h" -extern small_t *(tiles[]); extern size_t TILES; extern size_t TILE_WIDTH; extern size_t TILE_HEIGHT; -extern small_t tile_connections[]; +small_t *(tiles[TILES_CAP]); +small_t tile_connections[TILES_CAP]; void load_tiles() { @@ -33,6 +35,7 @@ void print_tiles() { for(size_t i = 0; i < TILES; i++) { + printf("%ld\n", i); for(size_t y = 0; y < TILE_HEIGHT; y++) { for(size_t x = 0; x < TILE_WIDTH; x++) @@ -43,7 +46,12 @@ void print_tiles() } } -void load_connections() +int get_tile_pixel(size_t t, size_t x, size_t y) +{ + return tiles[t][y * TILE_WIDTH + x]; +} + +small_t *load_tile_connections() { char file_path[32] = "files/tiles/tiles.dat"; FILE *fp = fopen(file_path, "rb"); @@ -55,11 +63,13 @@ void load_connections() fread(tile_connections, sizeof(small_t), TILES, fp); fclose(fp); + + return tile_connections; } #include <dirent.h> -size_t calc_tiles() +void calc_tiles() { size_t file_count = 0; DIR * dirp; @@ -73,5 +83,5 @@ size_t calc_tiles() } closedir(dirp); - return file_count-1; + TILES = file_count - 1; } diff --git a/src/tiles.h b/src/tiles.h index 2f5cd7b..cdf27e1 100644 --- a/src/tiles.h +++ b/src/tiles.h @@ -4,9 +4,9 @@ void load_tiles(); void free_tiles(); void print_tiles(); +int get_tile_pixel(size_t t, size_t x, size_t y); -void load_connections(); - -size_t calc_tiles(); +small_t *load_tile_connections(); +void calc_tiles(); #endif diff --git a/src/typedef.h b/src/typedef.h new file mode 100644 index 0000000..7bde436 --- /dev/null +++ b/src/typedef.h @@ -0,0 +1,12 @@ +#ifndef TYPEDEF_H +#define TYPEDEF_H + +#define TILES_CAP 63 +#define TILEMAP_CAP 4096 + +#include <stdint.h> +#include <stddef.h> +typedef uint8_t small_t; +typedef size_t big_t; + +#endif |