aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh1
-rw-r--r--src/gen_tiles.c168
-rw-r--r--src/main.c98
-rw-r--r--src/ppm.c16
-rw-r--r--src/ppm.h9
-rw-r--r--src/tiles.c64
-rw-r--r--src/tiles.h10
7 files changed, 268 insertions, 98 deletions
diff --git a/build.sh b/build.sh
index 6c4860e..13b73b1 100755
--- a/build.sh
+++ b/build.sh
@@ -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;
}
diff --git a/src/main.c b/src/main.c
index c169326..d474ae2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
diff --git a/src/ppm.c b/src/ppm.c
index caeff9b..22bfaa5 100644
--- a/src/ppm.c
+++ b/src/ppm.c
@@ -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);
}
diff --git a/src/ppm.h b/src/ppm.h
index f6dfd82..1fff658 100644
--- a/src/ppm.h
+++ b/src/ppm.h
@@ -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