aboutsummaryrefslogtreecommitdiff
path: root/src/tilemap.c
blob: df1c1c69048e9bad365bfadc92f71afbafa5212d (plain)
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
#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)

extern size_t TILES;
extern size_t SWIDTH;
extern 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 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()
{
    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);
}

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 generate_tile_masks(small_t (*tc)[SIDES_MAX])
{
    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] |= (tc[n][3-i] == tc[j][i]) << OFFSET;
            }
        }
    }
}
// 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");
//     }
// }