diff --git a/assets/fonts/JetBrainsMono-Regular.ttf b/assets/fonts/JetBrainsMono-Regular.ttf new file mode 100644 index 0000000..dff66cc Binary files /dev/null and b/assets/fonts/JetBrainsMono-Regular.ttf differ diff --git a/include/Sorter.hpp b/include/Sorter.hpp index fffd93a..b50094c 100644 --- a/include/Sorter.hpp +++ b/include/Sorter.hpp @@ -10,4 +10,6 @@ public: virtual bool isFinished() const = 0; virtual std::string getName() const = 0; virtual void reset() = 0; + virtual std::string getTimeComplexity() const = 0; + virtual std::string getSpaceComplexity() const = 0; }; diff --git a/include/UI.hpp b/include/UI.hpp index 74cb136..4bc741f 100644 --- a/include/UI.hpp +++ b/include/UI.hpp @@ -14,6 +14,8 @@ private: sf::Font font_; sf::Text algorithmText_; sf::Text stateText_; + sf::Text timeComplexityText_; + sf::Text spaceComplexityText_; sf::Text comparisonsText_; sf::Text swapsText_; sf::Text speedText_; diff --git a/include/sorters/BubbleSorter.hpp b/include/sorters/BubbleSorter.hpp index 2d8f8c4..471dd5d 100644 --- a/include/sorters/BubbleSorter.hpp +++ b/include/sorters/BubbleSorter.hpp @@ -9,6 +9,8 @@ public: bool isFinished() const override; std::string getName() const override; void reset() override; + std::string getTimeComplexity() const override; + std::string getSpaceComplexity() const override; private: enum class Phase { COMPARING, SWAPPING, NEXT }; diff --git a/include/sorters/InsertionSorter.hpp b/include/sorters/InsertionSorter.hpp index b9ca211..36657e6 100644 --- a/include/sorters/InsertionSorter.hpp +++ b/include/sorters/InsertionSorter.hpp @@ -9,6 +9,8 @@ public: bool isFinished() const override; std::string getName() const override; void reset() override; + std::string getTimeComplexity() const override; + std::string getSpaceComplexity() const override; private: enum class Phase { COMPARING, SHIFTING, INSERTING, NEXT }; diff --git a/include/sorters/MergeSorter.hpp b/include/sorters/MergeSorter.hpp index 45ac940..e22d9cd 100644 --- a/include/sorters/MergeSorter.hpp +++ b/include/sorters/MergeSorter.hpp @@ -10,6 +10,8 @@ public: bool isFinished() const override; std::string getName() const override; void reset() override; + std::string getTimeComplexity() const override; + std::string getSpaceComplexity() const override; private: enum class Phase { MERGING, COPYING_LEFT, COPYING_RIGHT, COPYING_BACK, NEXT_MERGE }; diff --git a/include/sorters/QuickSorter.hpp b/include/sorters/QuickSorter.hpp index 5f6749f..fb0e1ba 100644 --- a/include/sorters/QuickSorter.hpp +++ b/include/sorters/QuickSorter.hpp @@ -10,6 +10,8 @@ public: bool isFinished() const override; std::string getName() const override; void reset() override; + std::string getTimeComplexity() const override; + std::string getSpaceComplexity() const override; private: enum class Phase { PARTITIONING, SWAPPING_PIVOT, PUSHING_RANGES }; diff --git a/include/sorters/SelectionSorter.hpp b/include/sorters/SelectionSorter.hpp index a200fc9..400981c 100644 --- a/include/sorters/SelectionSorter.hpp +++ b/include/sorters/SelectionSorter.hpp @@ -9,6 +9,8 @@ public: bool isFinished() const override; std::string getName() const override; void reset() override; + std::string getTimeComplexity() const override; + std::string getSpaceComplexity() const override; private: enum class Phase { FINDING_MIN, SWAPPING, NEXT }; diff --git a/src/App.cpp b/src/App.cpp index 28db8c0..4046a9c 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -168,27 +168,66 @@ void App::update(float dt) { } void App::render() { - window_.clear(sf::Color(18, 18, 22)); + window_.clear(sf::Color(10, 12, 20)); float width = window_.getSize().x / static_cast(array_.getSize()); float maxVal = static_cast(array_.getSize()); + sf::VertexArray vertices(sf::Quads); + for (int i = 0; i < array_.getSize(); ++i) { float height = (array_.getValue(i) / maxVal) * (window_.getSize().y * 0.8f); + float x = i * width; + float y = window_.getSize().y - height; + + sf::Color barColor; + bool useGradient = false; - sf::RectangleShape bar(sf::Vector2f(width - 1.0f, height)); - bar.setPosition(i * width, window_.getSize().y - height); - switch (array_.getState(i)) { - case Array::State::NORMAL: bar.setFillColor(sf::Color(200, 200, 200)); break; - case Array::State::COMPARE: bar.setFillColor(sf::Color::Yellow); break; - case Array::State::SWAP: bar.setFillColor(sf::Color::Red); break; - case Array::State::SORTED: bar.setFillColor(sf::Color::Green); break; + case Array::State::NORMAL: + useGradient = true; + break; + case Array::State::COMPARE: + barColor = sf::Color(0, 220, 255); + break; + case Array::State::SWAP: + barColor = sf::Color(255, 120, 30); + break; + case Array::State::SORTED: + barColor = sf::Color(50, 220, 120); + break; + } + + if (useGradient) { + float normalizedValue = array_.getValue(i) / maxVal; + sf::Color bottomColor(60, 80, 140); + sf::Color topColor(160, 180, 255); + + sf::Color gradientTop( + static_cast(bottomColor.r + (topColor.r - bottomColor.r) * normalizedValue), + static_cast(bottomColor.g + (topColor.g - bottomColor.g) * normalizedValue), + static_cast(bottomColor.b + (topColor.b - bottomColor.b) * normalizedValue) + ); + + sf::Color gradientBottom( + static_cast(bottomColor.r + (topColor.r - bottomColor.r) * normalizedValue * 0.6f), + static_cast(bottomColor.g + (topColor.g - bottomColor.g) * normalizedValue * 0.6f), + static_cast(bottomColor.b + (topColor.b - bottomColor.b) * normalizedValue * 0.6f) + ); + + vertices.append(sf::Vertex(sf::Vector2f(x, window_.getSize().y), gradientBottom)); + vertices.append(sf::Vertex(sf::Vector2f(x + width - 1.0f, window_.getSize().y), gradientBottom)); + vertices.append(sf::Vertex(sf::Vector2f(x + width - 1.0f, y), gradientTop)); + vertices.append(sf::Vertex(sf::Vector2f(x, y), gradientTop)); + } else { + vertices.append(sf::Vertex(sf::Vector2f(x, window_.getSize().y), barColor)); + vertices.append(sf::Vertex(sf::Vector2f(x + width - 1.0f, window_.getSize().y), barColor)); + vertices.append(sf::Vertex(sf::Vector2f(x + width - 1.0f, y), barColor)); + vertices.append(sf::Vertex(sf::Vector2f(x, y), barColor)); } - - window_.draw(bar); } + window_.draw(vertices); ui_.draw(window_); window_.display(); diff --git a/src/UI.cpp b/src/UI.cpp index 070c3f3..aac61e4 100644 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -2,7 +2,7 @@ #include UI::UI() : fontLoaded_(false) { - if (!font_.loadFromFile("assets/fonts/Roboto-Regular.ttf")) { + if (!font_.loadFromFile("assets/fonts/JetBrainsMono-Regular.ttf")) { std::cerr << "Failed to load font" << std::endl; return; } @@ -19,20 +19,30 @@ UI::UI() : fontLoaded_(false) { stateText_.setFillColor(sf::Color::White); stateText_.setPosition(15.0f, 50.0f); + timeComplexityText_.setFont(font_); + timeComplexityText_.setCharacterSize(16); + timeComplexityText_.setFillColor(sf::Color(160, 160, 160)); + timeComplexityText_.setPosition(15.0f, 80.0f); + + spaceComplexityText_.setFont(font_); + spaceComplexityText_.setCharacterSize(16); + spaceComplexityText_.setFillColor(sf::Color(160, 160, 160)); + spaceComplexityText_.setPosition(15.0f, 105.0f); + comparisonsText_.setFont(font_); comparisonsText_.setCharacterSize(18); comparisonsText_.setFillColor(sf::Color(220, 220, 220)); - comparisonsText_.setPosition(15.0f, 80.0f); + comparisonsText_.setPosition(15.0f, 135.0f); swapsText_.setFont(font_); swapsText_.setCharacterSize(18); swapsText_.setFillColor(sf::Color(220, 220, 220)); - swapsText_.setPosition(15.0f, 105.0f); + swapsText_.setPosition(15.0f, 160.0f); speedText_.setFont(font_); speedText_.setCharacterSize(18); speedText_.setFillColor(sf::Color(220, 220, 220)); - speedText_.setPosition(15.0f, 130.0f); + speedText_.setPosition(15.0f, 185.0f); controlsText_.setFont(font_); controlsText_.setCharacterSize(15); @@ -63,6 +73,9 @@ void UI::update(const Sorter& sorter, bool isPlaying, bool isFinished, int steps } stateText_.setString(state); + timeComplexityText_.setString("Time: " + sorter.getTimeComplexity()); + spaceComplexityText_.setString("Space: " + sorter.getSpaceComplexity()); + comparisonsText_.setString("Comparisons: " + std::to_string(array.getComparisons())); swapsText_.setString("Swaps: " + std::to_string(array.getSwaps())); speedText_.setString("Speed: " + std::to_string(stepsPerFrame) + "x"); @@ -74,7 +87,7 @@ void UI::draw(sf::RenderWindow& window) { } float leftWidth = 350.0f; - float leftHeight = 160.0f; + float leftHeight = 215.0f; leftBackground_.setSize(sf::Vector2f(leftWidth, leftHeight)); leftBackground_.setPosition(5.0f, 5.0f); @@ -93,6 +106,8 @@ void UI::draw(sf::RenderWindow& window) { window.draw(algorithmText_); window.draw(stateText_); + window.draw(timeComplexityText_); + window.draw(spaceComplexityText_); window.draw(comparisonsText_); window.draw(swapsText_); window.draw(speedText_); diff --git a/src/sorters/BubbleSorter.cpp b/src/sorters/BubbleSorter.cpp index 4bdd452..0a6a652 100644 --- a/src/sorters/BubbleSorter.cpp +++ b/src/sorters/BubbleSorter.cpp @@ -63,6 +63,14 @@ std::string BubbleSorter::getName() const { return "Bubble Sort"; } +std::string BubbleSorter::getTimeComplexity() const { + return "O(n) / O(n²) / O(n²)"; +} + +std::string BubbleSorter::getSpaceComplexity() const { + return "O(1)"; +} + void BubbleSorter::reset() { i_ = 0; j_ = 0; diff --git a/src/sorters/InsertionSorter.cpp b/src/sorters/InsertionSorter.cpp index b2aad41..913ca93 100644 --- a/src/sorters/InsertionSorter.cpp +++ b/src/sorters/InsertionSorter.cpp @@ -67,6 +67,14 @@ std::string InsertionSorter::getName() const { return "Insertion Sort"; } +std::string InsertionSorter::getTimeComplexity() const { + return "O(n) / O(n²) / O(n²)"; +} + +std::string InsertionSorter::getSpaceComplexity() const { + return "O(1)"; +} + void InsertionSorter::reset() { i_ = 1; j_ = 0; diff --git a/src/sorters/MergeSorter.cpp b/src/sorters/MergeSorter.cpp index 0ea130a..b3f38a3 100644 --- a/src/sorters/MergeSorter.cpp +++ b/src/sorters/MergeSorter.cpp @@ -121,6 +121,14 @@ std::string MergeSorter::getName() const { return "Merge Sort"; } +std::string MergeSorter::getTimeComplexity() const { + return "O(n log n) / O(n log n) / O(n log n)"; +} + +std::string MergeSorter::getSpaceComplexity() const { + return "O(n)"; +} + void MergeSorter::reset() { currentSize_ = 1; leftStart_ = 0; diff --git a/src/sorters/QuickSorter.cpp b/src/sorters/QuickSorter.cpp index 3888fc9..5e3b42d 100644 --- a/src/sorters/QuickSorter.cpp +++ b/src/sorters/QuickSorter.cpp @@ -108,6 +108,14 @@ std::string QuickSorter::getName() const { return "Quick Sort"; } +std::string QuickSorter::getTimeComplexity() const { + return "O(n log n) / O(n log n) / O(n²)"; +} + +std::string QuickSorter::getSpaceComplexity() const { + return "O(log n)"; +} + void QuickSorter::reset() { stack_.clear(); currentLow_ = 0; diff --git a/src/sorters/SelectionSorter.cpp b/src/sorters/SelectionSorter.cpp index 10bdf0b..bb687ab 100644 --- a/src/sorters/SelectionSorter.cpp +++ b/src/sorters/SelectionSorter.cpp @@ -76,6 +76,14 @@ std::string SelectionSorter::getName() const { return "Selection Sort"; } +std::string SelectionSorter::getTimeComplexity() const { + return "O(n²) / O(n²) / O(n²)"; +} + +std::string SelectionSorter::getSpaceComplexity() const { + return "O(1)"; +} + void SelectionSorter::reset() { i_ = 0; j_ = 0;