1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "typedef.h"
#include "tilemap.h"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define BIG_SZ (sizeof(big_t) * 8)
#define INDEX ((__typeof(n))(n / BIG_SZ))
#define OFFSET ((__typeof(n))(n % BIG_SZ))
// from tiles.c
extern size_t TILES;
extern small_t tile_connections[TILES_CAP][SIDES_MAX];
size_t SWIDTH;
size_t SHEIGHT;
big_t (*tilemap)[TILEMAP_CAP];
size_t tsz = 0;
// 0 up 1 right
// 2 left 3 down
// 4 front 5 back
// 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][SIDES_MAX];
void generate_tile_masks()
{
tile_masks = malloc(sizeof(big_t[tsz][TILES_CAP][SIDES_MAX]));
memset(tile_masks, 0, sizeof(big_t[tsz][TILES_CAP][SIDES_MAX]));
for(size_t n = 0; n < TILES; n++)
{
for(size_t j = 0; j < TILES; j++) {
for(size_t i = 0; i < SIDES; i++) {
// current solution for circuits :(
// if(n == j && (n == 3 || n == 4 || n == 5 || n ==6))
// tile_masks[INDEX][j][i] |= (tc[n][3-i] != tc[j][i]) << OFFSET;
// else if(n == j && (n == 7|| n == 8 || n == 9 || n == 10))
// tile_masks[INDEX][j][i] |= 0 << OFFSET;
// else
tile_masks[INDEX][j][i] |= (tile_connections[n][3-i] == tile_connections[j][i]) << OFFSET;
}
}
}
}
void set(int t, int n)
{
tilemap[INDEX][t] |= ((big_t)1 << OFFSET);
}
int is_set(int t, int n)
{
return (tilemap[INDEX][t] >> OFFSET) & 1;
}
void init_tilemap(size_t width, size_t height)
{
SWIDTH = width;
SHEIGHT = height;
tsz = (TILES/BIG_SZ) + 1;
tilemap = malloc(sizeof(big_t[tsz][TILEMAP_CAP]));
// set everything
for(size_t n = 0; n < SWIDTH * SHEIGHT; n++)
for(size_t i = 0; i < tsz; i++)
tilemap[i][n] = (((big_t)1 << MIN(BIG_SZ, (TILES - (i*BIG_SZ)))) - 1);
generate_tile_masks();
}
void destroy_tilemap()
{
free(tilemap);
free(tile_masks);
}
int has_collapsed(int t)
{
return is_set(t, TILES);
}
int get_collapsed_tile(int t)
{
for(size_t i = 0; i < TILES; i++)
if(is_set(t, i)) return i;
return TILES;
}
void collapse(int t, int n)
{
for(size_t i = 0; i < tsz; i++)
tilemap[i][t] = 0;
set(t, n);
set(t, TILES);
}
size_t count_entropy(int t)
{
if(has_collapsed(t)) return TILES+1;
size_t c = 0;
for (size_t j = 0; j < TILES; j++)
c += is_set(t, j);
return c;
}
void mask(int t, int m, int r)
{
for(size_t i = 0; i < tsz; i++)
tilemap[i][t] &= tile_masks[i][m][r];
}
// void print_tilemap()
// {
// printf("tsz: %ld\n", tsz);
// for(size_t i = 0; i < SHEIGHT; i++) {
// for(size_t j = 0; j < SWIDTH; j++) {
// for(size_t n = tsz-1; n < tsz; n--)
// printf("%lb ", tilemap[n][i*SWIDTH + j]);
// printf("\n");
// }
// printf("\n");
// }
// }
|