diff options
Diffstat (limited to 'src/sandbox.cpp')
-rw-r--r-- | src/sandbox.cpp | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/src/sandbox.cpp b/src/sandbox.cpp index f71be9b..27cd654 100644 --- a/src/sandbox.cpp +++ b/src/sandbox.cpp @@ -1,6 +1,7 @@ #include "sandbox.hpp" #include "common.hpp" +#include <cstring> #include <utility> // Copied from IM_COL32 @@ -14,7 +15,7 @@ static constexpr uint32_t MAT_COLOR_LUT[] = { }; uint32_t Tile::get_color() const { - return MAT_COLOR_LUT[std::to_underlying(mat)]; + return MAT_COLOR_LUT[std::to_underlying(so)]; } Sandbox::Sandbox(int w, int h) @@ -22,65 +23,90 @@ Sandbox::Sandbox(int w, int h) , _a(w * h) // TODO random seed , _pcg() - , _solid_tile{ Tile::SOLID } + , _wall_tile{ Tile::ROCK } , width{ w } , height{ h } // { + memset(_bitmap.data(), 0xff, _bitmap.size() * sizeof(_bitmap[0])); + set_sand(10, 10, Tile{ .so = Tile::SAND }); } static void simulate_sand_tile(Sandbox& self, int x, int y) { - auto& at0 = self.gs(x, y); - switch (at0.mat) { + const auto at0 = self.gs(x, y); + if (at0.updated) { + // Clear update bit for next cycle + self.gs(x, y).updated = false; + return; + } + + switch (at0.so) { case Tile::AIR: break; - case Tile::SOLID: break; + case Tile::ROCK: 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; + const auto below = self.gs(x, y - 1); + if (below.so == Tile::AIR) { + self.set_sand(x, y, below); + self.set_sand(x, y - 1, at0); + } else { + Pt loc1[]{ Pt(x - 1, y + 1), Pt(x + 1, y + 1) }; + auto bound = 2; + auto which = self._pcg.next_u32(bound); + for (int i = 0; i < bound; ++i) { + // Try going to a side + auto at1 = self.gs(loc1[i].x, loc1[i].y); + if (at1.so == Tile::AIR) { + self.set_sand(x, y, at1); + self.set_sand(loc1[i].x, loc1[i].y, at0); } + which = (which + 1) % bound; } - } else { - // Try going to a side - // TODO } } break; - - case Tile::WATER: { - // TODO pressure system - } break; } + + if (at0.so == Tile::AIR) + switch (at0.fl) { + case Tile::NOTHING: break; + + case 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.fl == Tile::WATER) { + // auto p = neigh.fmass; + // max_pressure = max_pressure > p ? max_pressure : p; + // } + // } + } 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); + _x = _y = 0; + for (; _y < height; ++_y) { + for (; _x < width; ++_x) { + simulate_sand_tile(*this, _x, _y); } + _x = 0; } ++ncycle; } Tile& Sandbox::gs(int x, int y) { if (x < 0 || x >= width || y < 0 || y >= height) - return _solid_tile; + return _wall_tile; return _a[y * width + x]; } void Sandbox::set_sand(int x, int y, Tile sand) { - _a[y * width + x] = std::move(sand); + auto& target = _a[y * width + x]; + target = sand; + // Set update bit if the target is after cursor + if (y > _y || x > _x) + target.updated = true; _bitmap[y * width + x] = sand.get_color(); } |