From a68cc52b5c5d1c104de8d675b90816aaa39f4ace Mon Sep 17 00:00:00 2001 From: kartofen Date: Tue, 9 Aug 2022 00:35:47 +0300 Subject: nearly works --- src/main.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/ppm.c | 40 +++++++-------- src/ppm.h | 4 +- src/tiles.c | 2 +- 4 files changed, 183 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 1db4858..645ac76 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,175 @@ #include +#include +#include +#include +#include #include "tiles.h" #include "ppm.h" #define TILES 5 int *(tiles[TILES]) = {0}; -int TILE_WIDTH; -int TILE_HEIGHT; +size_t TILE_WIDTH; +size_t TILE_HEIGHT; + +int tile_masks[TILES][4] = { + { 0b00011, 0b00101, 0b01001, 0b10001 }, + + { 0b11100, 0b11010, 0b10110, 0b10001 }, + { 0b11100, 0b11010, 0b01001, 0b01110 }, + { 0b11100, 0b00101, 0b10110, 0b01110 }, + { 0b00011, 0b11010, 0b10110, 0b01110 } +}; + +#define WIDTH_SCALER 3 +#define HEIGHT_SCALER 3 + +int tiles_board[WIDTH_SCALER * HEIGHT_SCALER] = {0}; + +void init_tiles_board() +{ + for(int i = 0; i < WIDTH_SCALER * HEIGHT_SCALER; i++) + tiles_board[i] = (1 << TILES) - 1; +} + +int count_1s(int v) +{ + if(((v >> TILES) & 1) == 1) return TILES+1; + + v &= (1 << TILES) - 1; + + int c = 0; + for (c = 0; v; v >>= 1) + c += v & 1; + + return c; +} + +int get_least_entropy_index() +{ + // array of indexes with the least entropy + int least_entpy[WIDTH_SCALER * HEIGHT_SCALER]; + size_t least_entpy_sz = 0; + + for(int i = 0; i < HEIGHT_SCALER; i++) + { + for (int j = 0; j < WIDTH_SCALER; j++) + { + int index = i * WIDTH_SCALER + 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]]); + + if(b1s == l1s) { + 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 set_index(int i) +{ + if(count_1s(tiles_board[i]) == 1) { + tiles_board[i] |= 1 << TILES; + goto modify_neighbors; + } + + // bad way + int n; + while(((tiles_board[i] >> TILES) & 1) != 1) + { + n = rand() % TILES; + if(((tiles_board[i] >> n) & 1) != 1) + continue; + + tiles_board[i] = 0; + tiles_board[i] |= 1 << n; + tiles_board[i] |= 1 << TILES; + } + +modify_neighbors: + + 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 % 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 % WIDTH_SCALER != 0) // left + if(count_1s(tiles_board[i-1]) != (TILES + 1)) + tiles_board[i-1] &= tile_masks[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]; + +} int main(void) { + time_t seed = time(0); + srand(420); + printf("seed %ld\n", seed); + + init_tiles_board(); load_tiles(TILES); + print_tiles(TILES); + + while(1) { + int lei; + lei = get_least_entropy_index(); + + if(count_1s(tiles_board[lei]) == TILES+1) + break; // every index is set + else + set_index(lei); + + // for(int i = 0; i < HEIGHT_SCALER; i++) { + // for(int j = 0; j < WIDTH_SCALER; j++) + // printf("%6b ", tiles_board[i * WIDTH_SCALER + j]); + // putchar('\n'); + // } + // putchar('\n'); + } + + 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)); + + for(int i = 0; i < HEIGHT_SCALER; i++) + { + for(int j = 0; j < WIDTH_SCALER; j++) + { + int 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++) { + image[(y+(i*TILE_HEIGHT)) * img_wdt + (x+(j*TILE_WIDTH))] = tiles[t][y * TILE_WIDTH + x]; + } + } + } + } + + save_as_ppm("file.ppm", image, img_wdt, img_hgt); + free(image); + free_tiles(TILES); return 0; } diff --git a/src/ppm.c b/src/ppm.c index 7ac29f3..a39b9cb 100644 --- a/src/ppm.c +++ b/src/ppm.c @@ -3,7 +3,7 @@ #include #include "ppm.h" -void save_as_ppm(char* file_path, int *t, int width, int height) +void save_as_ppm(char* file_path, int *t, size_t width, size_t height) { FILE *fp = fopen(file_path, "wb"); if(!fp) { @@ -11,34 +11,34 @@ void save_as_ppm(char* file_path, int *t, int width, int height) exit(EXIT_FAILURE); } - fprintf(fp, "P6\n%d %d 255\n", width, height); + // fprintf(fp, "P6\n%ld %ld 255\n", width, height); - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) - { - char c = (t[i * width + j] == 0) ? 255 : 0; - for(int j = 0; j < 3; j++) - fwrite(&c, 1, 1, fp); - } - - // int scaler = 10; - - // fprintf(fp, "P6\n%d %d 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; i++) + // for(size_t j = 0; j < width; j++) // { - // char c = (t[(i/scaler) * width + (j/scaler)] == 0) ? 255 : 0; + // char c = (t[i * width + j] == 0) ? 255 : 0; // for(int j = 0; j < 3; j++) // fwrite(&c, 1, 1, fp); // } + int scaler = 5; + + fprintf(fp, "P6\n%d %d 255\n", width*scaler, height*scaler); + + for(int i = 0; i < height * scaler; i++) + for(int j = 0; j < width * scaler; j++) + { + char c = (t[(i/scaler) * width + (j/scaler)] == 0) ? 255 : 0; + for(int j = 0; j < 3; j++) + fwrite(&c, 1, 1, fp); + } + fclose(fp); } -int *load_from_ppm(char *file_path, int *width, int *height) +int *load_from_ppm(char *file_path, size_t *width, size_t *height) { FILE *fp = fopen(file_path, "rb"); if(!fp) { @@ -64,8 +64,8 @@ int *load_from_ppm(char *file_path, int *width, int *height) fread(pixels, *width*3, *height, fp); int *t = malloc((*width) * (*height ) * sizeof(int)); - for(int i = 0; i < *height; i++) - for(int j = 0; j < *width; j++) + 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; free(pixels); diff --git a/src/ppm.h b/src/ppm.h index b68e77c..8ef66cc 100644 --- a/src/ppm.h +++ b/src/ppm.h @@ -1,9 +1,9 @@ #ifndef PPM_H #define PPM_H -void save_as_ppm(char* file_path, int *t, int width, int height); +void save_as_ppm(char* file_path, int *t, size_t width, size_t height); -int *load_from_ppm(char *file_path, int *width, int *height); +int *load_from_ppm(char *file_path, size_t *width, size_t *height); void free_ppm(int *img); diff --git a/src/tiles.c b/src/tiles.c index b09ca95..40608b3 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -7,7 +7,7 @@ extern int TILE_HEIGHT; void load_tiles(int n) { - int width, height; + size_t width, height; for(int i = 0; i < n; i++) { char file_path[26]; -- cgit v1.2.3