#pragma once #include "Bubble.h" #include "Castle.h" #include "Fish.h" #include "Seaweed.h" #include "Waterline.h" #include #include extern int g_maxCells; class Aquarium { private: int width; int height; struct Cell { char ch = ' '; char colorChar = 'k'; // Default to black bool bold = false; bool operator==(const Cell &other) const { return ch == other.ch && colorChar == other.colorChar && bold == other.bold; } bool operator!=(const Cell &other) const { return !(*this == other); } }; struct LayeredCell { std::vector> layers; // Sorted by layer (ascending) }; std::vector> frontBuffer; std::vector> backBuffer; std::vector> layeredMap; inline static const std::unordered_map colorCharToPair = { {'r', 1}, // Red {'g', 2}, // Green {'y', 3}, // Yellow {'b', 4}, // Blue {'m', 5}, // Magenta {'c', 6}, // Cyan {'w', 7}, // White {'k', 8} // Black }; inline void applyColorAttr(char colorChar, bool enable) const { bool bold = std::isupper(colorChar); char lowerChar = std::tolower(static_cast(colorChar)); auto it = colorCharToPair.find(lowerChar); if (it != colorCharToPair.end()) { int colorPairId = it->second; if (enable) { attron(COLOR_PAIR(colorPairId)); if (bold) attron(A_BOLD); } else { attroff(COLOR_PAIR(colorPairId)); if (bold) attroff(A_BOLD); } } } std::vector> fishes; std::vector> bubbles; std::vector> seaweeds; std::unique_ptr waterline; std::unique_ptr castle; public: Aquarium(); ~Aquarium(); static Aquarium &getInstance() { static Aquarium instance; return instance; } [[nodiscard]] int getWidth() const { return width; } [[nodiscard]] int getHeight() const { return height; } void addFish(); void addBubble(size_t x, size_t y); void addSeaweed(); void addWaterline(); void addCastle(); void redraw(); void initColors(); void initColorLookup(); void resize(); void clearBackBuffer(); void drawToBackBuffer(int y, int x, int layer, const std::string &line, const std::string &colorLine); void removeFromBackBuffer(int y, int x, int layer, const std::string &line); void applyBackBuffer(); };