Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/Game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Game

void syncZooDataForRendering();

void prepareInventoryDisplay();

sf::RenderWindow m_window;
unsigned int m_windowWidth, m_windowHeight;
sf::Font m_font;
Expand Down Expand Up @@ -93,4 +95,6 @@ class Game
bool m_showingInventory;
sf::RectangleShape m_showInventoryButton;
sf::Text m_showInventoryButtonText;
};
sf::RectangleShape m_inventoryBackground;
std::vector<sf::Text> m_inventoryTexts;
};
2 changes: 2 additions & 0 deletions include/Zoo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class Zoo
void syncInventoryWithHabitats();
void displayAllInventories() const;

std::string getInventorySummary() const;

// Methods using template functions
float calculateAverageAnimalHealth() const;
int calculateTotalAnimalValue() const;
Expand Down
61 changes: 56 additions & 5 deletions src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ Game::Game()
m_isDeletingObject(false),
m_deletingObjectIndex(-1),
m_zoo("Default Zoo", {}, 0, true),
m_showingInventory(false)
m_showingInventory(false),
m_inventoryBackground(),
m_inventoryTexts()
{
m_window.create(sf::VideoMode(m_windowWidth, m_windowHeight), "Zoo Tycoon - Enter Zoo Name");
if (!m_font.loadFromFile("fonts/DUSHICK.otf"))
Expand Down Expand Up @@ -199,6 +201,10 @@ Game::Game()
m_showInventoryButton.getPosition().y + (m_showInventoryButton.getSize().y - textBounds.height) / 2 - 5
);

m_inventoryBackground.setFillColor(sf::Color(0, 0, 0, 200));
m_inventoryBackground.setOutlineColor(sf::Color::White);
m_inventoryBackground.setOutlineThickness(2);

loadTexture(m_pathTexture, "images/path.png", "../images/path.png", sf::Color(153, 102, 51));

m_statusMessage.setFont(m_font);
Expand Down Expand Up @@ -252,9 +258,8 @@ void Game::processEvents()
if (m_showInventoryButton.getGlobalBounds().contains(mousePos.x, mousePos.y)) {
m_showingInventory = !m_showingInventory;
if (m_showingInventory) {
m_zoo.syncInventoryWithHabitats();
m_zoo.displayAllInventories();
m_statusMessage.setString("Inventory displayed in console");
prepareInventoryDisplay();
m_statusMessage.setString("Showing inventory");
m_statusMessage.setFillColor(sf::Color::Green);
} else {
m_statusMessage.setString("");
Expand Down Expand Up @@ -718,6 +723,9 @@ void Game::handleResize(unsigned int width, unsigned int height)
m_showInventoryButton.getPosition().x + (m_showInventoryButton.getSize().x - textBounds.width) / 2,
m_showInventoryButton.getPosition().y + (m_showInventoryButton.getSize().y - textBounds.height) / 2 - 5
);

if (m_showingInventory)
prepareInventoryDisplay();
float btnWidth = 120, btnHeight = 40;
float startX = m_buildHabitatButton.getPosition().x;
float startY = m_buildHabitatButton.getPosition().y + m_buildHabitatButton.getSize().y + 10;
Expand Down Expand Up @@ -1196,6 +1204,13 @@ void Game::render()
m_window.draw(m_animalOptionTexts[i]);
}

if (m_showingInventory)
{
m_window.draw(m_inventoryBackground);
for (const auto &text : m_inventoryTexts)
m_window.draw(text);
}

sf::Text budgetText;
budgetText.setFont(m_font);
budgetText.setCharacterSize(20);
Expand Down Expand Up @@ -1240,4 +1255,40 @@ bool Game::loadTexture(sf::Texture& texture, const std::string& primaryPath, con
texture.loadFromImage(fallbackImage);
std::cout << "Using fallback texture" << std::endl;
return false;
}
}

void Game::prepareInventoryDisplay()
{
m_inventoryTexts.clear();
m_zoo.syncInventoryWithHabitats();
std::string summary = m_zoo.getInventorySummary();
std::istringstream iss(summary);
std::string line;
float padding = 10.f;
float maxWidth = 0.f;
while (std::getline(iss, line))
{
sf::Text text;
text.setFont(m_font);
text.setCharacterSize(14);
text.setFillColor(sf::Color::White);
text.setString(line);
m_inventoryTexts.push_back(text);
float w = text.getLocalBounds().width;
if (w > maxWidth)
maxWidth = w;
}

float backgroundWidth = maxWidth + 2 * padding;
float backgroundHeight = (m_inventoryTexts.size() * 18.f) + 2 * padding;
m_inventoryBackground.setSize(sf::Vector2f(backgroundWidth, backgroundHeight));
m_inventoryBackground.setPosition((m_windowWidth - backgroundWidth) / 2.f,
(m_windowHeight - backgroundHeight) / 2.f);

float currentY = m_inventoryBackground.getPosition().y + padding;
for (auto &text : m_inventoryTexts)
{
text.setPosition(m_inventoryBackground.getPosition().x + padding, currentY);
currentY += 18.f;
}
}
80 changes: 79 additions & 1 deletion src/Zoo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../include/exception/AnimalException.hpp"
#include <algorithm>
#include <random>
#include <sstream>

Zoo::Zoo(const std::string &name, const std::vector<Habitat> &habitats, int visitor_count, bool is_open, float budget)
: m_name(name), m_habitats(habitats), m_visitorCount(visitor_count), m_isOpen(is_open), m_budget(budget)
Expand Down Expand Up @@ -135,6 +136,27 @@ void Zoo::displayAllInventories() const {
m_habitatInventory.displayInventory();
}

std::string Zoo::getInventorySummary() const {
std::ostringstream oss;
oss << "=== " << m_allAnimalsInventory.getName() << " (" << m_allAnimalsInventory.getCount()
<< "/" << m_allAnimalsInventory.getCapacity() << ") ===\n";
size_t idx = 1;
for (const auto &animal : m_allAnimalsInventory.getItems()) {
if (animal) {
oss << idx++ << ". " << *animal << "\n";
}
}
oss << "\n=== " << m_habitatInventory.getName() << " (" << m_habitatInventory.getCount()
<< "/" << m_habitatInventory.getCapacity() << ") ===\n";
idx = 1;
for (const auto &hab : m_habitatInventory.getItems()) {
if (hab) {
oss << idx++ << ". " << *hab << "\n";
}
}
return oss.str();
}

bool Zoo::spendMoney(float amount)
{
if (m_budget >= amount)
Expand Down Expand Up @@ -439,4 +461,60 @@ void Zoo::highlightHabitatAt(sf::RenderWindow& window, int tileSize, int index,
if (index >= 0 && index < static_cast<int>(m_habitats.size())) {
m_habitats[index].highlightHabitat(window, tileSize, color, 2.0f);
}
}
}
float Zoo::calculateAverageAnimalHealth() const {
int count = 0;
float total = 0.f;
for (const auto& habitat : m_habitats) {
for (const auto& animal : habitat.getAnimals()) {
if (animal) {
total += animal->getIsHealthy();
++count;
}
}
}
return count > 0 ? total / count : 0.f;
}

int Zoo::calculateTotalAnimalValue() const {
int total = 0;
for (const auto& habitat : m_habitats) {
for (const auto& animal : habitat.getAnimals()) {
if (animal) total += animal->getPrice();
}
}
return total;
}

float Zoo::calculateAverageHabitatCleanliness() const {
if (m_habitats.empty()) return 0.f;
float total = 0.f;
for (const auto& habitat : m_habitats) {
total += habitat.getCleanlinessLevel();
}
return total / static_cast<float>(m_habitats.size());
}

int Zoo::calculateTotalHabitatCapacity() const {
int total = 0;
for (const auto& habitat : m_habitats) {
total += habitat.getCapacity();
}
return total;
}

void Zoo::displayHealthyAnimals(float minHealthThreshold) const {
std::cout << "\nAnimals with health >= " << minHealthThreshold << ':' << std::endl;
m_allAnimalsInventory.forEachItem([&](const std::shared_ptr<Animal>& animal){
if (animal && animal->getIsHealthy() >= minHealthThreshold)
std::cout << *animal << std::endl;
});
}

void Zoo::displayExpensiveAnimals(int minPrice) const {
std::cout << "\nAnimals costing at least $" << minPrice << ':' << std::endl;
m_allAnimalsInventory.forEachItem([&](const std::shared_ptr<Animal>& animal){
if (animal && animal->getPrice() >= minPrice)
std::cout << *animal << std::endl;
});
}