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 | 
