#include "Waterline.h" #include "../core/Aquarium.h" #include "../utils/Random.h" #include "../utils/defs.h" Waterline::Waterline() : Entity(0, WATERLINE_Y) { shape[0] = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; shape[1] = "^^^^ ^^^ ^^^ ^^^ ^^^^ "; shape[2] = "^^^^ ^^^^ ^^^ ^^ "; shape[3] = "^^ ^^^^ ^^^ ^^^^^^ "; const size_t width = Aquarium::getInstance().getWidth(); for (size_t i = 0; i < NUM_WAVE_LAYERS; ++i) { const std::string &original = shape[i]; const size_t pattern_len = original.length(); // Calculate how many full patterns + remainder we need const size_t full_patterns = width / pattern_len; const size_t remainder = width % pattern_len; shape[i].reserve(width); for (size_t p = 0; p < full_patterns; ++p) { shape[i] += original; } if (remainder > 0) { shape[i] += original.substr(0, remainder); } // Create color line colorLines[i].assign(shape[i].size(), WATERLINE_COLOR); } // Initialize cache vectors cached_image.assign(shape.begin(), shape.end()); cached_mask.assign(colorLines.begin(), colorLines.end()); } void Waterline::update() noexcept { // Use cached probability calculations static constexpr float thresholds[NUM_WAVE_LAYERS] = { 0.0f, // Layer 0 never moves 0.25f / WAVE_MOVE_CHANCE, 0.5f / WAVE_MOVE_CHANCE, 0.75f / WAVE_MOVE_CHANCE}; for (size_t i = 1; i < NUM_WAVE_LAYERS; ++i) { if (Random::floatInRange(0.0f, 1.0f) < thresholds[i]) { if (Random::intInRange(0, 1) == 0) { shiftStringLeft(shape[i]); } else { shiftStringRight(shape[i]); } } } // Update cached vectors std::copy(shape.begin(), shape.end(), cached_image.begin()); std::copy(colorLines.begin(), colorLines.end(), cached_mask.begin()); } void Waterline::shiftStringLeft(std::string &str) { if (!str.empty()) { char first = str.front(); str.erase(0, 1); str.push_back(first); } } void Waterline::shiftStringRight(std::string &str) { if (!str.empty()) { char last = str.back(); str.pop_back(); str.insert(0, 1, last); } } const std::vector &Waterline::getImage() const { return cached_image; } const std::vector &Waterline::getMask() const { return cached_mask; }