diff options
| -rwxr-xr-x | build.sh | 1 | ||||
| -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 | 
7 files changed, 268 insertions, 98 deletions
| @@ -17,6 +17,7 @@ function run {  function leak {      VALGRND="valgrind --leak-check=full" +    RUN=1  }  function clean { 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 | 
