aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2022-08-10 17:18:45 +0300
committerkartofen <mladenovnasko0@gmail.com>2022-08-10 17:18:45 +0300
commit851a3f34efd456295b21849199c3eaf4e70f9fb9 (patch)
tree7eff274bf1ea6b144254a0ebb063257ab2b33af0 /src
parentbb820d973e9f53d33a32c46659e2a163e68be4ba (diff)
big refactor
Diffstat (limited to 'src')
-rw-r--r--src/gen_tiles.c3
-rw-r--r--src/main.c151
-rw-r--r--src/ppm.c1
-rw-r--r--src/ppm.h3
-rw-r--r--src/tilemap.c93
-rw-r--r--src/tilemap.h17
-rw-r--r--src/tiles.c20
-rw-r--r--src/tiles.h6
-rw-r--r--src/typedef.h12
9 files changed, 189 insertions, 117 deletions
diff --git a/src/gen_tiles.c b/src/gen_tiles.c
index fbfe378..e70990e 100644
--- a/src/gen_tiles.c
+++ b/src/gen_tiles.c
@@ -2,9 +2,10 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include "typedef.h"
#include "ppm.h"
-#define TILES 5
+#define TILES 2
#define TILE_WIDTH 3
#define TILE_HEIGHT 3
#define TILE_SZ ((TILE_WIDTH) * (TILE_HEIGHT))
diff --git a/src/main.c b/src/main.c
index 1725434..353efe1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,88 +2,38 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "tiles.h"
+#include "typedef.h"
#include "ppm.h"
+#include "tiles.h"
+#include "tilemap.h"
-#define TILES_CAP 63
size_t TILES;
+
size_t TILE_WIDTH;
size_t TILE_HEIGHT;
-small_t *(tiles[TILES_CAP]) = {0};
-
-// 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];
-
-// 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 30
-#define HEIGHT_SCALER 30
-
-size_t tiles_board[WIDTH_SCALER * HEIGHT_SCALER] = {0};
-
-void generate_tile_masks()
-{
- 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];
- }
- }
-}
-
-size_t count_1s(int v)
-{
- if(((v >> TILES) & 1) == 1) return TILES+1;
-
- v &= (1 << TILES) - 1;
-
- size_t c = 0;
- for (c = 0; v; v >>= 1)
- c += v & 1;
-
- return c;
-}
+size_t SWIDTH = 10;
+size_t SHEIGHT = 10;
int get_least_entropy_index()
{
// array of indexes with the least entropy
- int least_entpy[WIDTH_SCALER * HEIGHT_SCALER];
+ int least_entpy[TILEMAP_CAP];
size_t least_entpy_sz = 0;
- for(int i = 0; i < HEIGHT_SCALER; i++)
+ for(size_t i = 0; i < SHEIGHT; i++)
{
- for (int j = 0; j < WIDTH_SCALER; j++)
+ for (size_t j = 0; j < SWIDTH; j++)
{
- int index = i * WIDTH_SCALER + j;
+ size_t index = i * SWIDTH + 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]]);
+ size_t b1s = count_entropy(index);
+ size_t l1s = count_entropy(least_entpy[least_entpy_sz-1]);
if(b1s == l1s) {
least_entpy[least_entpy_sz++] = index;
@@ -98,11 +48,11 @@ int get_least_entropy_index()
}
-void set_index(int i)
+void collapse_this(int i)
{
int n = 0;
- if(count_1s(tiles_board[i]) == 0) {
+ if(count_entropy(i) == 0) {
fprintf(stderr, "ERROR: No possible tiles for this position: %d\n", i);
exit(EXIT_FAILURE);
}
@@ -110,80 +60,71 @@ void set_index(int i)
// this bad
do {
n = rand() % TILES;
- if(((tiles_board[i] >> n) & 1) != 1)
+ if(!(is_set(i, n)))
continue;
- tiles_board[i] = 0;
- tiles_board[i] |= (1 << n);
- tiles_board[i] |= (1 << TILES);
- } while(((tiles_board[i] >> TILES) & 1) != 1);
+ collapse(i, n);
+ } while(!(has_collapsed(i)));
- 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 / SWIDTH != 0) // up
+ if(!(has_collapsed(i-SWIDTH)))
+ mask(i-SWIDTH, 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 % SWIDTH != (SWIDTH - 1)) // right
+ if(!(has_collapsed(i+1)))
+ mask(i+1, 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 % SWIDTH != 0) // left
+ if(!(has_collapsed(i-1)))
+ mask(i-1, 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];
+ if(i / SWIDTH != (SHEIGHT - 1)) // down
+ if(!(has_collapsed(i+SWIDTH)))
+ mask(i+SWIDTH, n, 3);
}
int main(void)
{
- TILES = calc_tiles();
+ calc_tiles();
if(TILES > TILES_CAP) {
printf("ERROR: Too many tiles: %ld\n", TILES);
exit(EXIT_FAILURE);
}
- time_t seed = time(0);
+ time_t seed = 420;
srand(seed);
printf("The Seed is %ld\n", seed);
- load_connections();
- generate_tile_masks();
-
- // init tiles board
- for(int i = 0; i < WIDTH_SCALER * HEIGHT_SCALER; i++)
- tiles_board[i] = (1 << TILES) - 1;
+ generate_tile_masks(load_tile_connections());
+ init_tilemap();
while(1) {
int lei;
lei = get_least_entropy_index();
- if(count_1s(tiles_board[lei]) == TILES+1)
+ if(has_collapsed(lei))
break; // every index is set
else
- set_index(lei);
+ collapse_this(lei);
}
load_tiles();
- size_t img_wdt = TILE_WIDTH * WIDTH_SCALER;
- size_t img_hgt = TILE_HEIGHT * HEIGHT_SCALER;
- small_t *image = malloc(img_wdt * img_hgt);
+ size_t img_wdt = TILE_WIDTH * SWIDTH;
+ size_t img_hgt = TILE_HEIGHT * SHEIGHT;
+ small_t *image = malloc(img_wdt * img_hgt * sizeof(small_t));
memset(image, 0, img_wdt * img_hgt);
- for(size_t i = 0; i < HEIGHT_SCALER; i++)
+ for(size_t i = 0; i < SHEIGHT; i++)
{
- for(size_t j = 0; j < WIDTH_SCALER; j++)
+ for(size_t j = 0; j < SWIDTH; j++)
{
- size_t t;
- for(t = 0; t < TILES; t++)
- if(((tiles_board[i * WIDTH_SCALER + j] >> t) & 1) == 1) break;
-
- 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];
- }
- }
+ size_t t = get_collapsed_tile(i * SWIDTH + j);
+ if(t == TILES) exit(-124);
+
+ 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))] = get_tile_pixel(t, x, y);
}
}
diff --git a/src/ppm.c b/src/ppm.c
index 22bfaa5..cd62205 100644
--- a/src/ppm.c
+++ b/src/ppm.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "typedef.h"
#include "ppm.h"
void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler)
diff --git a/src/ppm.h b/src/ppm.h
index 1fff658..70bd6f0 100644
--- a/src/ppm.h
+++ b/src/ppm.h
@@ -1,9 +1,6 @@
#ifndef PPM_H
#define PPM_H
-#include <stdint.h>
-typedef uint8_t small_t;
-
void save_as_ppm(char* file_path, small_t *t, size_t width, size_t height, size_t scaler);
small_t *load_from_ppm(char *file_path, size_t *width, size_t *height);
diff --git a/src/tilemap.c b/src/tilemap.c
new file mode 100644
index 0000000..70d534f
--- /dev/null
+++ b/src/tilemap.c
@@ -0,0 +1,93 @@
+#include "typedef.h"
+#include "tilemap.h"
+
+extern size_t TILES;
+extern size_t SWIDTH;
+extern size_t SHEIGHT;
+
+big_t tilemap[TILEMAP_CAP];
+
+// 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
+big_t tile_masks[TILES_CAP][4];
+
+void set(int i, int n)
+{
+ tilemap[i] |= (1 << n);
+}
+
+int is_set(int i, int n)
+{
+ return (tilemap[i] >> n) & 1;
+}
+
+void init_tilemap()
+{
+ for(size_t i = 0; i < SWIDTH * SHEIGHT; i++)
+ for(size_t n = 0; n < TILES; n++)
+ set(i, n);
+}
+
+size_t count_entropy(int i)
+{
+ if(has_collapsed(i)) return TILES+1;
+
+ size_t c = 0;
+ for (size_t j = 0; j < TILES; j++)
+ c += is_set(i, j);
+
+ return c;
+}
+
+void collapse(int i, int n)
+{
+ tilemap[i] = 0;
+ set(i, n);
+ set(i, TILES);
+}
+
+int has_collapsed(int i)
+{
+ return is_set(i, TILES);
+}
+
+int get_collapsed_tile(int i)
+{
+ for(size_t t = 0; t < TILES; t++)
+ if(is_set(i, t)) return t;
+
+ return TILES;
+}
+
+
+void mask(int i, int m, int r)
+{
+ tilemap[i] &= tile_masks[m][r];
+}
+
+void generate_tile_masks(small_t* tile_connections)
+{
+ 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];
+ }
+ }
+}
diff --git a/src/tilemap.h b/src/tilemap.h
new file mode 100644
index 0000000..e945f06
--- /dev/null
+++ b/src/tilemap.h
@@ -0,0 +1,17 @@
+#ifndef TILEMAP_H
+#define TILEMAP_H
+
+void set(int i, int n);
+int is_set(int i, int n);
+
+void mask(int i, int m, int r);
+void generate_tile_masks(small_t* tile_connections);
+
+void init_tilemap();
+
+size_t count_entropy(int i);
+void collapse(int i, int n);
+int has_collapsed(int i);
+int get_collapsed_tile(int i);
+
+#endif
diff --git a/src/tiles.c b/src/tiles.c
index 2432736..6b7a39b 100644
--- a/src/tiles.c
+++ b/src/tiles.c
@@ -1,14 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
+#include "typedef.h"
+#include "tiles.h"
#include "ppm.h"
-extern small_t *(tiles[]);
extern size_t TILES;
extern size_t TILE_WIDTH;
extern size_t TILE_HEIGHT;
-extern small_t tile_connections[];
+small_t *(tiles[TILES_CAP]);
+small_t tile_connections[TILES_CAP];
void load_tiles()
{
@@ -33,6 +35,7 @@ void print_tiles()
{
for(size_t i = 0; i < TILES; i++)
{
+ printf("%ld\n", i);
for(size_t y = 0; y < TILE_HEIGHT; y++)
{
for(size_t x = 0; x < TILE_WIDTH; x++)
@@ -43,7 +46,12 @@ void print_tiles()
}
}
-void load_connections()
+int get_tile_pixel(size_t t, size_t x, size_t y)
+{
+ return tiles[t][y * TILE_WIDTH + x];
+}
+
+small_t *load_tile_connections()
{
char file_path[32] = "files/tiles/tiles.dat";
FILE *fp = fopen(file_path, "rb");
@@ -55,11 +63,13 @@ void load_connections()
fread(tile_connections, sizeof(small_t), TILES, fp);
fclose(fp);
+
+ return tile_connections;
}
#include <dirent.h>
-size_t calc_tiles()
+void calc_tiles()
{
size_t file_count = 0;
DIR * dirp;
@@ -73,5 +83,5 @@ size_t calc_tiles()
}
closedir(dirp);
- return file_count-1;
+ TILES = file_count - 1;
}
diff --git a/src/tiles.h b/src/tiles.h
index 2f5cd7b..cdf27e1 100644
--- a/src/tiles.h
+++ b/src/tiles.h
@@ -4,9 +4,9 @@
void load_tiles();
void free_tiles();
void print_tiles();
+int get_tile_pixel(size_t t, size_t x, size_t y);
-void load_connections();
-
-size_t calc_tiles();
+small_t *load_tile_connections();
+void calc_tiles();
#endif
diff --git a/src/typedef.h b/src/typedef.h
new file mode 100644
index 0000000..7bde436
--- /dev/null
+++ b/src/typedef.h
@@ -0,0 +1,12 @@
+#ifndef TYPEDEF_H
+#define TYPEDEF_H
+
+#define TILES_CAP 63
+#define TILEMAP_CAP 4096
+
+#include <stdint.h>
+#include <stddef.h>
+typedef uint8_t small_t;
+typedef size_t big_t;
+
+#endif