aboutsummaryrefslogtreecommitdiff
path: root/src/tilemap.c
blob: efd0b4ee76d6b365352e203bf4bcef716596fee6 (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
125
126
#include <stdlib.h>
#include <string.h>
#include "typedef.h"
#include "tilemap.h"

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

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
// 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 t, int n)
{
    tilemap[(n/64)][t] |= (1 << (n%64));
}

int is_set(int t, int n)
{
    return (tilemap[(n/64)][t] >> (n%64)) & 1;
}

void init_tilemap()
{
    // 63 max tiles in 64 bit int
    tsz = (TILES/64) + 1;
    tilemap = malloc(sizeof(big_t[tsz][TILEMAP_CAP]));

    for(size_t i = 0; i < tsz; i++)
        for(size_t n = 0; n < SWIDTH * SHEIGHT; n++)
            tilemap[i][n] = ((1 << MIN(63, TILES)) - 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* tile_connections)
{
    size_t (*wt_con)[4];
    size_t (*no_con)[4];
    wt_con = malloc(sizeof(size_t[tsz][4]));
    no_con = malloc(sizeof(size_t[tsz][4]));

    for(int n = 0; n < 4; n++)
    {
        for(size_t i = 0; i < tsz; i++) {
            wt_con[i][n] = 0;
            no_con[i][n] = 0;
        }

        for(size_t i = 0; i < TILES; i++)
            wt_con[(i/64)][n] |= ((tile_connections[i] >> n) & 1) << (i%64);

        for(size_t i = 0; i < TILES; i++)
            no_con[(i/64)][n] |= ((wt_con[(i/64)][n] >> (i%64)) & 1) ? 0 : 1 << (i % 64);
    }

    tile_masks = malloc(sizeof(big_t[tsz][TILES_CAP][4]));

    for(size_t i = 0; i < TILES; i++)
    {
        for(int n = 0; n < 4; n++)
        {
            if((tile_connections[i] >> (3-n)) & 1)
                for(size_t t = 0; t < tsz; t++)
                    tile_masks[t][i][n] = wt_con[t][n];
            else
                for(size_t t = 0; t < tsz; t++)
                     tile_masks[t][i][n] = no_con[t][n];
        }
    }

    free(wt_con);
    free(no_con);
}