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
|
#include "sandbox.hpp"
#include "common.hpp"
#include <utility>
// Copied from IM_COL32
#define COL_U32(r, g, b, a) (((uint32_t)(A) << IM_COL32_A_SHIFT) | ((uint32_t)(B) << IM_COL32_B_SHIFT) | ((uint32_t)(G) << IM_COL32_G_SHIFT) | ((uint32_t)(R) << IM_COL32_R_SHIFT))
static constexpr uint32_t MAT_COLOR_LUT[] = {
0xffffff'ff, // AIR
0xababab'ff, // SOLID
0xfffca8'ff, // SAND
0x435bf7'ff, // WATER
};
uint32_t Tile::get_color() const {
return MAT_COLOR_LUT[std::to_underlying(mat)];
}
Sandbox::Sandbox(int w, int h)
: _bitmap(w * h)
, _a(w * h)
// TODO random seed
, _pcg()
, _solid_tile{ Tile::SOLID }
, width{ w }
, height{ h } //
{
}
static void simulate_sand_tile(Sandbox& self, int x, int y) {
auto& at0 = self.gs(x, y);
switch (at0.mat) {
case Tile::AIR: break;
case Tile::SOLID: break;
case Tile::SAND: {
auto& below = self.gs(x, y - 1);
if (below.mat == Tile::AIR) {
below = at0;
below.updated = true;
at0 = {};
at0.updated = true;
} else if (below.mat == Tile::WATER) {
Pt neighs[]{ Pt(x - 1, y), Pt(x + 1, y), Pt(x, y + 1), Pt(x, y - 1) };
int max_pressure = 0;
for (auto [x1, y1] : neighs) {
auto& neigh = self.gs(x1, y1);
if (neigh.mat == Tile::WATER) {
auto p = neigh.pressure;
max_pressure = max_pressure > p ? max_pressure : p;
}
}
} else {
// Try going to a side
// TODO
}
} break;
case Tile::WATER: {
// TODO pressure system
} break;
}
}
void Sandbox::simulate_step() {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
simulate_sand_tile(*this, x, y);
}
}
++ncycle;
}
Tile& Sandbox::gs(int x, int y) {
if (x < 0 || x >= width || y < 0 || y >= height)
return _solid_tile;
return _a[y * width + x];
}
void Sandbox::set_sand(int x, int y, Tile sand) {
_a[y * width + x] = std::move(sand);
_bitmap[y * width + x] = sand.get_color();
}
// std::vector<uint32_t> Sandbox::to_bitmap() const {
// // TODO
// }
|