#include #include #include #include #include "tiles.h" #include "ppm.h" #define TILES 6 int *(tiles[TILES]) = {0}; size_t TILE_WIDTH; size_t TILE_HEIGHT; int tile_masks[TILES][4] = { { 0b000011, 0b000101, 0b001001, 0b010001 }, { 0b111100, 0b111010, 0b110110, 0b010001 }, { 0b111100, 0b111010, 0b001001, 0b101110 }, { 0b111100, 0b000101, 0b110110, 0b101110 }, { 0b000011, 0b111010, 0b110110, 0b101110 }, { 0b111100, 0b111010, 0b110110, 0b101110 } }; #define WIDTH_SCALER 10 #define HEIGHT_SCALER 10 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) { int n; if(count_1s(tiles_board[i]) == 0) { fprintf(stderr, "ERROR: No possible tiles for this position: %d\n", i); exit(EXIT_FAILURE); } // this bad do { 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; } while(((tiles_board[i] >> TILES) & 1) != 1); 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(seed); printf("seed %ld\n", seed); init_tiles_board(); 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); } load_tiles(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)); for(size_t i = 0; i < HEIGHT_SCALER; i++) { for(size_t 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]; } } } } free_tiles(TILES); char file_name[64] = {0}; sprintf(file_name, "files/file_%ld.ppm", seed); printf("Saved file with name: %s\n", file_name); save_as_ppm(file_name, image, img_wdt, img_hgt, 10); free(image); return 0; }