diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 162 |
1 files changed, 160 insertions, 2 deletions
@@ -1,17 +1,175 @@ #include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <time.h> #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; } |