diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen_tiles.c | 168 | ||||
-rw-r--r-- | src/main.c | 98 | ||||
-rw-r--r-- | src/ppm.c | 16 | ||||
-rw-r--r-- | src/ppm.h | 9 | ||||
-rw-r--r-- | src/tiles.c | 64 | ||||
-rw-r--r-- | src/tiles.h | 10 |
6 files changed, 267 insertions, 98 deletions
diff --git a/src/gen_tiles.c b/src/gen_tiles.c index 3133805..fecba4e 100644 --- a/src/gen_tiles.c +++ b/src/gen_tiles.c @@ -1,55 +1,149 @@ #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <sys/stat.h> #include "ppm.h" -int tile_0[9] = { - 0, 0, 0, - 0, 0, 0, - 0, 0, 0 -}; +#define TILES 3 +#define TILE_WIDTH 3 +#define TILE_HEIGHT 3 +#define TILE_SZ ((TILE_WIDTH) * (TILE_HEIGHT)) -int tile_1[9] = { - 0, 1, 0, - 1, 1, 1, - 0, 0, 0 -}; +FILE *fp; -int tile_2[9] = { - 0, 1, 0, - 0, 1, 1, - 0, 1, 0 -}; +// possible types: X T I +char symetry[TILES] = "XTI"; -int tile_3[9] = { - 0, 1, 0, - 1, 1, 0, - 0, 1, 0 +small_t tiles[TILES][TILE_SZ] = { + { + 0, 0, 0, + 0, 0, 0, + 0, 0, 0 + }, { + 0, 1, 0, + 1, 1, 1, + 0, 0, 0 + // }, { + // 0, 1, 0, + // 1, 1, 1, + // 0, 1, 0 + },{ + 0, 0, 0, + 1, 1, 1, + 0, 0, 0 + } }; -int tile_4[9] = { - 0, 0, 0, - 1, 1, 1, - 0, 1, 0 -}; -int tile_5[9] = { - 0, 1, 0, - 1, 1, 1, - 0, 1, 0 +small_t tiles_connections[TILES][4] = { + { 0, 0, 0, 0 }, + { 1, 1, 1, 0 }, + // { 1, 1, 1, 1 }, + { 0, 1, 1, 0 }, }; -void gen() +int rotate(int x, int y, int r) +{ + switch(r) { + case 0: // no roatate + return y * TILE_WIDTH + x; + case 1: // right + return (TILE_SZ-TILE_WIDTH) + y - (x * TILE_WIDTH); + case 2: // left + return (TILE_WIDTH-1) - y + (x * TILE_WIDTH); + case 3: // down + return (TILE_SZ-1) - (y * TILE_WIDTH) - x; + } + + return -1; +} + +int crotate(int n, int r) +{ + switch(r) { + case 0: + return n; + case 1: + return (n + 1) % 4; + case 2: + return (n + 2) % 4; + case 3: + return (n + 3) % 4; + } + + return -1; +} + +void rotate_tiles(small_t *tile, int i, int r) +{ + for(size_t y = 0; y < TILE_HEIGHT; y++) + for(size_t x = 0; x < TILE_WIDTH; x++) + tile[y * TILE_WIDTH + x] = tiles[i][rotate(x, y, r)]; +} + +void rotate_connections(small_t *tc, int i, int r) { - mkdir("files/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - save_as_ppm("files/tile_0.ppm", tile_0, 3, 3, 1); - save_as_ppm("files/tile_1.ppm", tile_1, 3, 3, 1); - save_as_ppm("files/tile_2.ppm", tile_2, 3, 3, 1); - save_as_ppm("files/tile_3.ppm", tile_3, 3, 3, 1); - save_as_ppm("files/tile_4.ppm", tile_4, 3, 3, 1); - save_as_ppm("files/tile_5.ppm", tile_5, 3, 3, 1); + for(int j = 0; j < 4; j++) + tc[j] = tiles_connections[i][crotate(j, r)]; } +void save(small_t *t, small_t *n, int i) +{ + char file_name[64] = {0}; + + sprintf(file_name, "files/tiles/tile_%d.ppm", i); + save_as_ppm(file_name, t, TILE_WIDTH, TILE_HEIGHT, 1); + printf("Saved file: %s\n", file_name); + + small_t connections = 0; + for(int c = 0; c < 4; c++) + { + connections |= (n[c] << (3-c)); + } + + fwrite(&connections, sizeof(connections), 1, fp); +} + +void gen_rotations() +{ + mkdir("files", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + mkdir("files/tiles", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fp = fopen("files/tiles/tiles.dat", "wb"); + + for(int i = 0, r = 0; i < TILES; i++) + { + small_t tile[TILE_SZ]; + small_t tile_connections[4]; + switch(symetry[i]) + { + case 'X': + save(tiles[i], tiles_connections[i], i+r); + break; + case 'T': ; + for(; r < 4; r++) { + rotate_tiles(tile, i, r); + rotate_connections(tile_connections, i, r); + + save(tile, tile_connections, i+r); + } + r--; + break; + case 'I': + save(tiles[i], tiles_connections[i], i+r); + r++; + rotate_tiles(tile, i, 2); + rotate_connections(tile_connections, i, 2); + save(tile, tile_connections, i+r); + break; + } + } + + fclose(fp); +} + + int main(void) { - gen(); + gen_rotations(); return 0; } @@ -5,41 +5,60 @@ #include "tiles.h" #include "ppm.h" -#define TILES 6 - -int *(tiles[TILES]) = {0}; +#define TILES_CAP 63 +size_t TILES; size_t TILE_WIDTH; size_t TILE_HEIGHT; -int tile_masks[TILES][4] = { - { 0b000011, 0b000101, 0b001001, 0b010001 }, +small_t *(tiles[TILES_CAP]) = {0}; - { 0b111100, 0b111010, 0b110110, 0b010001 }, - { 0b111100, 0b111010, 0b001001, 0b101110 }, - { 0b111100, 0b000101, 0b110110, 0b101110 }, - { 0b000011, 0b111010, 0b110110, 0b101110 }, +// 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]; - { 0b111100, 0b111010, 0b110110, 0b101110 } -}; +// 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 10 -#define HEIGHT_SCALER 10 +#define WIDTH_SCALER 100 +#define HEIGHT_SCALER 100 -int tiles_board[WIDTH_SCALER * HEIGHT_SCALER] = {0}; +size_t tiles_board[WIDTH_SCALER * HEIGHT_SCALER] = {0}; -void init_tiles_board() +void generate_tile_masks() { - for(int i = 0; i < WIDTH_SCALER * HEIGHT_SCALER; i++) - tiles_board[i] = (1 << TILES) - 1; + 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]; + } + } } -int count_1s(int v) +size_t count_1s(int v) { if(((v >> TILES) & 1) == 1) return TILES+1; v &= (1 << TILES) - 1; - int c = 0; + size_t c = 0; for (c = 0; v; v >>= 1) c += v & 1; @@ -81,7 +100,7 @@ int get_least_entropy_index() void set_index(int i) { - int n; + int n = 0; if(count_1s(tiles_board[i]) == 0) { fprintf(stderr, "ERROR: No possible tiles for this position: %d\n", i); @@ -95,8 +114,8 @@ void set_index(int i) continue; tiles_board[i] = 0; - tiles_board[i] |= 1 << n; - tiles_board[i] |= 1 << TILES; + tiles_board[i] |= (1 << n); + tiles_board[i] |= (1 << TILES); } while(((tiles_board[i] >> TILES) & 1) != 1); if(i / WIDTH_SCALER != 0) // up @@ -118,11 +137,22 @@ void set_index(int i) int main(void) { + TILES = calc_tiles(); + if(TILES > TILES_CAP) { + printf("ERROR: Too many tiles: %ld\n", TILES); + exit(EXIT_FAILURE); + } + time_t seed = time(0); srand(seed); printf("The Seed is %ld\n", seed); - init_tiles_board(); + load_connections(); + generate_tile_masks(); + + // init tiles board + for(int i = 0; i < WIDTH_SCALER * HEIGHT_SCALER; i++) + tiles_board[i] = (1 << TILES) - 1; while(1) { int lei; @@ -134,36 +164,36 @@ int main(void) set_index(lei); } - load_tiles(TILES); + load_tiles(); - int img_wdt = TILE_WIDTH * WIDTH_SCALER; - int img_hgt = TILE_HEIGHT * HEIGHT_SCALER; - int *image = malloc(img_wdt * img_hgt * sizeof(int)); - memset(image, 0, img_wdt * img_hgt * sizeof(int)); + size_t img_wdt = TILE_WIDTH * WIDTH_SCALER; + size_t img_hgt = TILE_HEIGHT * HEIGHT_SCALER; + small_t *image = malloc(img_wdt * img_hgt); + memset(image, 0, img_wdt * img_hgt); for(size_t i = 0; i < HEIGHT_SCALER; i++) { for(size_t j = 0; j < WIDTH_SCALER; j++) { - int t; + size_t t; for(t = 0; t < TILES; t++) if(((tiles_board[i * WIDTH_SCALER + j] >> t) & 1) == 1) break; - for(int y = 0; y < TILE_HEIGHT; y++) { - for(int x = 0; x < TILE_WIDTH; x++) { + 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]; } } } } - free_tiles(TILES); + free_tiles(); char file_name[64] = {0}; - sprintf(file_name, "files/file_%ld.ppm", seed); - printf("Saved file with name: %s\n", file_name); + sprintf(file_name, "files/file_%ld.ppm", seed); save_as_ppm(file_name, image, img_wdt, img_hgt, 10); + printf("Saved file with name: %s\n", file_name); free(image); return 0; @@ -3,7 +3,7 @@ #include <string.h> #include "ppm.h" -void save_as_ppm(char* file_path, int *t, size_t width, size_t height, size_t scaler) +void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler) { FILE *fp = fopen(file_path, "wb"); if(!fp) { @@ -12,14 +12,14 @@ void save_as_ppm(char* file_path, int *t, size_t width, size_t height, size_t sc } if(scaler == 0) { - fprintf(stderr, "ERROR: Invalid value for scaler %d\n", scaler); + fprintf(stderr, "ERROR: Invalid value for scaler %ld\n", scaler); exit(EXIT_FAILURE); } - fprintf(fp, "P6\n%d %d 255\n", width*scaler, height*scaler); + fprintf(fp, "P6\n%ld %ld 255\n", width*scaler, height*scaler); - for(int i = 0; i < height * scaler; i++) - for(int j = 0; j < width * scaler; j++) + for(size_t i = 0; i < height * scaler; i++) + for(size_t j = 0; j < width * scaler; j++) { char c = (t[(i/scaler) * width + (j/scaler)] == 0) ? 255 : 0; for(int j = 0; j < 3; j++) @@ -30,7 +30,7 @@ void save_as_ppm(char* file_path, int *t, size_t width, size_t height, size_t sc fclose(fp); } -int *load_from_ppm(char *file_path, size_t *width, size_t *height) +small_t *load_from_ppm(char *file_path, size_t *width, size_t *height) { FILE *fp = fopen(file_path, "rb"); if(!fp) { @@ -55,7 +55,7 @@ int *load_from_ppm(char *file_path, size_t *width, size_t *height) fread(pixels, *width*3, *height, fp); - int *t = malloc((*width) * (*height ) * sizeof(int)); + small_t *t = malloc((*width) * (*height)); for(size_t i = 0; i < *height; i++) for(size_t j = 0; j < *width; j++) t[i * *width + j] = (pixels[(i * *width + j) * 3] == 0) ? 1 : 0; @@ -67,7 +67,7 @@ int *load_from_ppm(char *file_path, size_t *width, size_t *height) return t; } -void free_ppm(int *t) +void free_ppm(small_t *t) { free(t); } @@ -1,10 +1,13 @@ #ifndef PPM_H #define PPM_H -void save_as_ppm(char* file_path, int *t, size_t width, size_t height, size_t scaler); +#include <stdint.h> +typedef uint8_t small_t; -int *load_from_ppm(char *file_path, size_t *width, size_t *height); +void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler); -void free_ppm(int *img); +small_t *load_from_ppm(char *file_path, size_t *width, size_t *height); + +void free_ppm(small_t *img); #endif diff --git a/src/tiles.c b/src/tiles.c index 40608b3..2432736 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -1,39 +1,77 @@ #include <stdio.h> +#include <stdlib.h> #include "ppm.h" -extern int *(tiles[]); -extern int TILE_WIDTH; -extern int TILE_HEIGHT; +extern small_t *(tiles[]); +extern size_t TILES; -void load_tiles(int n) +extern size_t TILE_WIDTH; +extern size_t TILE_HEIGHT; + +extern small_t tile_connections[]; + +void load_tiles() { size_t width, height; - for(int i = 0; i < n; i++) + for(size_t i = 0; i < TILES; i++) { - char file_path[26]; - sprintf(file_path, "files/tile_%d.ppm", i); + char file_path[32]; + sprintf(file_path, "files/tiles/tile_%ld.ppm", i); tiles[i] = load_from_ppm(file_path, &width, &height); } TILE_WIDTH = width; TILE_HEIGHT = height; } -void free_tiles(int n) +void free_tiles() { - for(int i = 0; i < n; i++) + for(size_t i = 0; i < TILES; i++) free_ppm(tiles[i]); } -void print_tiles(int n) +void print_tiles() { - for(int i = 0; i < n; i++) + for(size_t i = 0; i < TILES; i++) { - for(int y = 0; y < TILE_HEIGHT; y++) + for(size_t y = 0; y < TILE_HEIGHT; y++) { - for(int x = 0; x < TILE_WIDTH; x++) + for(size_t x = 0; x < TILE_WIDTH; x++) putchar(tiles[i][y * TILE_WIDTH + x] + '0'); putchar('\n'); } putchar('\n'); } } + +void load_connections() +{ + char file_path[32] = "files/tiles/tiles.dat"; + FILE *fp = fopen(file_path, "rb"); + if(!fp) { + fprintf(stderr, "Could not open file: %s\n", file_path); + exit(EXIT_FAILURE); + } + + fread(tile_connections, sizeof(small_t), TILES, fp); + + fclose(fp); +} + +#include <dirent.h> + +size_t calc_tiles() +{ + size_t file_count = 0; + DIR * dirp; + struct dirent * entry; + + dirp = opendir("files/tiles"); /* There should be error handling after this */ + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_REG) { /* If the entry is a regular file */ + file_count++; + } + } + closedir(dirp); + + return file_count-1; +} diff --git a/src/tiles.h b/src/tiles.h index 14e4dd8..2f5cd7b 100644 --- a/src/tiles.h +++ b/src/tiles.h @@ -1,8 +1,12 @@ #ifndef TILES_H #define TILES_H -void load_tiles(int n); -void free_tiles(int n); -void print_tiles(int n); +void load_tiles(); +void free_tiles(); +void print_tiles(); + +void load_connections(); + +size_t calc_tiles(); #endif |