fissh

termios terminal aquarium. demo at ssh://fish@kloet.net
Download | Log | Files | Refs

Waterline.cpp (2328B)


      1 #include "Waterline.h"
      2 #include "../core/Aquarium.h"
      3 #include "../utils/Random.h"
      4 #include "../utils/defs.h"
      5 
      6 Waterline::Waterline() : Entity(0, WATERLINE_Y) {
      7   shape[0] = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
      8   shape[1] = "^^^^ ^^^  ^^^   ^^^    ^^^^      ";
      9   shape[2] = "^^^^      ^^^^     ^^^    ^^     ";
     10   shape[3] = "^^      ^^^^      ^^^    ^^^^^^  ";
     11 
     12   const size_t width = Aquarium::getInstance().getWidth();
     13 
     14   for (size_t i = 0; i < NUM_WAVE_LAYERS; ++i) {
     15     const std::string &original = shape[i];
     16     const size_t pattern_len = original.length();
     17 
     18     // Calculate how many full patterns + remainder we need
     19     const size_t full_patterns = width / pattern_len;
     20     const size_t remainder = width % pattern_len;
     21 
     22     shape[i].reserve(width);
     23     for (size_t p = 0; p < full_patterns; ++p) {
     24       shape[i] += original;
     25     }
     26     if (remainder > 0) {
     27       shape[i] += original.substr(0, remainder);
     28     }
     29 
     30     // Create color line
     31     colorLines[i].assign(shape[i].size(), WATERLINE_COLOR);
     32   }
     33 
     34   // Initialize cache vectors
     35   cached_image.assign(shape.begin(), shape.end());
     36   cached_mask.assign(colorLines.begin(), colorLines.end());
     37 }
     38 
     39 void Waterline::update() noexcept {
     40   // Use cached probability calculations
     41   static constexpr float thresholds[NUM_WAVE_LAYERS] = {
     42       0.0f, // Layer 0 never moves
     43       0.25f / WAVE_MOVE_CHANCE, 0.5f / WAVE_MOVE_CHANCE,
     44       0.75f / WAVE_MOVE_CHANCE};
     45 
     46   for (size_t i = 1; i < NUM_WAVE_LAYERS; ++i) {
     47     if (Random::floatInRange(0.0f, 1.0f) < thresholds[i]) {
     48       if (Random::intInRange(0, 1) == 0) {
     49         shiftStringLeft(shape[i]);
     50       } else {
     51         shiftStringRight(shape[i]);
     52       }
     53     }
     54   }
     55 
     56   // Update cached vectors
     57   std::copy(shape.begin(), shape.end(), cached_image.begin());
     58   std::copy(colorLines.begin(), colorLines.end(), cached_mask.begin());
     59 }
     60 
     61 void Waterline::shiftStringLeft(std::string &str) {
     62   if (!str.empty()) {
     63     char first = str.front();
     64     str.erase(0, 1);
     65     str.push_back(first);
     66   }
     67 }
     68 
     69 void Waterline::shiftStringRight(std::string &str) {
     70   if (!str.empty()) {
     71     char last = str.back();
     72     str.pop_back();
     73     str.insert(0, 1, last);
     74   }
     75 }
     76 
     77 const std::vector<std::string> &Waterline::getImage() const {
     78   return cached_image;
     79 }
     80 
     81 const std::vector<std::string> &Waterline::getMask() const {
     82   return cached_mask;
     83 }