aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh16
-rw-r--r--src/main.c162
-rw-r--r--src/ppm.c40
-rw-r--r--src/ppm.h4
-rw-r--r--src/tiles.c2
5 files changed, 194 insertions, 30 deletions
diff --git a/build.sh b/build.sh
index 9d242c3..84a12e8 100755
--- a/build.sh
+++ b/build.sh
@@ -1,22 +1,28 @@
#!/bin/sh
+
cd ${0%/*} # go to project root
set -xe
-FLAGS="-Wall -Wextra -g"
+FLAGS="-Wall -Wextra -g -pedantic"
SRCD="src"
ODIR="obj"
BIN="bin"
+VALGRND=""
+
+function leak {
+ VALGRND="valgrind --leak-check=full"
+}
function clean {
rm -rf $BIN
rm -rf $ODIR
rm -rf files
+ kill $( ps -q $$ -o pgid= )
}
if ! { [[ $# -eq 0 ]]; } 2> /dev/null
then
- ($1)
- exit 0;
+ $1
fi
mkdir -p $ODIR
@@ -31,5 +37,5 @@ gcc -o $BIN/wfc $ODIR/main.o $ODIR/ppm.o $ODIR/tiles.o $FLAGS
gcc -o $BIN/gen_tiles $ODIR/gen_tiles.o $ODIR/ppm.o $FLAGS
-$BIN/gen_tiles
-$BIN/wfc
+$VALGRND $BIN/gen_tiles
+$VALGRND $BIN/wfc
diff --git a/src/main.c b/src/main.c
index 1db4858..645ac76 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,17 +1,175 @@
#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
#include "tiles.h"
#include "ppm.h"
#define TILES 5
int *(tiles[TILES]) = {0};
-int TILE_WIDTH;
-int TILE_HEIGHT;
+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;
}
diff --git a/src/ppm.c b/src/ppm.c
index 7ac29f3..a39b9cb 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, int width, int height)
+void save_as_ppm(char* file_path, int *t, size_t width, size_t height)
{
FILE *fp = fopen(file_path, "wb");
if(!fp) {
@@ -11,34 +11,34 @@ void save_as_ppm(char* file_path, int *t, int width, int height)
exit(EXIT_FAILURE);
}
- fprintf(fp, "P6\n%d %d 255\n", width, height);
+ // fprintf(fp, "P6\n%ld %ld 255\n", width, height);
- for(int i = 0; i < height; i++)
- for(int j = 0; j < width; j++)
- {
- char c = (t[i * width + j] == 0) ? 255 : 0;
- for(int j = 0; j < 3; j++)
- fwrite(&c, 1, 1, fp);
- }
-
- // int scaler = 10;
-
- // fprintf(fp, "P6\n%d %d 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; i++)
+ // for(size_t j = 0; j < width; j++)
// {
- // char c = (t[(i/scaler) * width + (j/scaler)] == 0) ? 255 : 0;
+ // char c = (t[i * width + j] == 0) ? 255 : 0;
// for(int j = 0; j < 3; j++)
// fwrite(&c, 1, 1, fp);
// }
+ int scaler = 5;
+
+ fprintf(fp, "P6\n%d %d 255\n", width*scaler, height*scaler);
+
+ for(int i = 0; i < height * scaler; i++)
+ for(int j = 0; j < width * scaler; j++)
+ {
+ char c = (t[(i/scaler) * width + (j/scaler)] == 0) ? 255 : 0;
+ for(int j = 0; j < 3; j++)
+ fwrite(&c, 1, 1, fp);
+ }
+
fclose(fp);
}
-int *load_from_ppm(char *file_path, int *width, int *height)
+int *load_from_ppm(char *file_path, size_t *width, size_t *height)
{
FILE *fp = fopen(file_path, "rb");
if(!fp) {
@@ -64,8 +64,8 @@ int *load_from_ppm(char *file_path, int *width, int *height)
fread(pixels, *width*3, *height, fp);
int *t = malloc((*width) * (*height ) * sizeof(int));
- for(int i = 0; i < *height; i++)
- for(int j = 0; j < *width; j++)
+ 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;
free(pixels);
diff --git a/src/ppm.h b/src/ppm.h
index b68e77c..8ef66cc 100644
--- a/src/ppm.h
+++ b/src/ppm.h
@@ -1,9 +1,9 @@
#ifndef PPM_H
#define PPM_H
-void save_as_ppm(char* file_path, int *t, int width, int height);
+void save_as_ppm(char* file_path, int *t, size_t width, size_t height);
-int *load_from_ppm(char *file_path, int *width, int *height);
+int *load_from_ppm(char *file_path, size_t *width, size_t *height);
void free_ppm(int *img);
diff --git a/src/tiles.c b/src/tiles.c
index b09ca95..40608b3 100644
--- a/src/tiles.c
+++ b/src/tiles.c
@@ -7,7 +7,7 @@ extern int TILE_HEIGHT;
void load_tiles(int n)
{
- int width, height;
+ size_t width, height;
for(int i = 0; i < n; i++)
{
char file_path[26];