#include #include #include "typedef.h" #include "tilemap.h" #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #define BIG_SZ (sizeof(big_t) * 8) extern size_t TILES; extern size_t SWIDTH; extern size_t SHEIGHT; big_t (*tilemap)[TILEMAP_CAP]; size_t tsz = 0; // 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 t, int n) { tilemap[(n/BIG_SZ)][t] |= (1 << (n%BIG_SZ)); } int is_set(int t, int n) { return (tilemap[(n/BIG_SZ)][t] >> (n%BIG_SZ)) & 1; } void init_tilemap() { tsz = (TILES/BIG_SZ) + 1; tilemap = malloc(sizeof(big_t[tsz][TILEMAP_CAP])); for(size_t i = 0; i < tsz; i++) for(size_t n = 0; n < SWIDTH * SHEIGHT; n++) tilemap[i][n] = ((1 << MIN(BIG_SZ, (TILES - (i*BIG_SZ)))) - 1); } void destroy_tilemap() { free(tilemap); free(tile_masks); } int has_collapsed(int t) { return is_set(t, TILES); } int get_collapsed_tile(int t) { for(size_t i = 0; i < TILES; i++) if(is_set(t, i)) return i; return TILES; } void collapse(int t, int n) { for(size_t i = 0; i < tsz; i++) tilemap[i][t] = 0; set(t, n); set(t, TILES); } size_t count_entropy(int t) { if(has_collapsed(t)) return TILES+1; size_t c = 0; for (size_t j = 0; j < TILES; j++) c += is_set(t, j); return c; } void mask(int t, int m, int r) { for(size_t i = 0; i < tsz; i++) tilemap[i][t] &= tile_masks[i][m][r]; } void generate_tile_masks(small_t* tile_connections) { size_t (*wt_con)[4]; size_t (*no_con)[4]; wt_con = malloc(sizeof(size_t[tsz][4])); no_con = malloc(sizeof(size_t[tsz][4])); for(int n = 0; n < 4; n++) { for(size_t i = 0; i < tsz; i++) { wt_con[i][n] = 0; no_con[i][n] = 0; } for(size_t i = 0; i < TILES; i++) wt_con[(i/BIG_SZ)][n] |= ((tile_connections[i] >> n) & 1) << (i%BIG_SZ); for(size_t i = 0; i < TILES; i++) no_con[(i/BIG_SZ)][n] |= ((wt_con[(i/BIG_SZ)][n] >> (i%BIG_SZ)) & 1) ? 0 : 1 << (i % BIG_SZ); } tile_masks = malloc(sizeof(big_t[tsz][TILES_CAP][4])); for(size_t i = 0; i < TILES; i++) { for(int n = 0; n < 4; n++) { if((tile_connections[i] >> (3-n)) & 1) for(size_t t = 0; t < tsz; t++) tile_masks[t][i][n] = wt_con[t][n]; else for(size_t t = 0; t < tsz; t++) tile_masks[t][i][n] = no_con[t][n]; } } free(wt_con); free(no_con); }