#include #include #include #include #include #include "tiles.h" #include "ppm.h" #define TILES 5 int *(tiles[TILES]) = {0}; 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; }