From 5a05f3f768f44e2919c3a4c69a7146a4d69a8e1e Mon Sep 17 00:00:00 2001 From: Gabriel Valenzuela Date: Wed, 2 Apr 2025 20:15:37 -0300 Subject: [PATCH 1/5] add(pila_cola): Base code --- include/characters/caravana.hpp | 95 +++++++++++++++++++ include/characters/chracterVisitant.hpp | 51 ++++++++++ include/characters/hermanosDeAcero.hpp | 94 ++++++++++++++++++ include/dataStructures/queue.hpp | 119 +++++++++++++++++++++++ include/dataStructures/stack.hpp | 121 ++++++++++++++++++++++++ tests/unit/list_test.cpp | 70 ++++++++++++++ tests/unit/queue_test.cpp | 36 +++++++ tests/unit/stack_test.cpp | 35 +++++++ 8 files changed, 621 insertions(+) create mode 100644 include/characters/caravana.hpp create mode 100644 include/characters/chracterVisitant.hpp create mode 100644 include/characters/hermanosDeAcero.hpp create mode 100644 include/dataStructures/queue.hpp create mode 100644 include/dataStructures/stack.hpp create mode 100644 tests/unit/list_test.cpp create mode 100644 tests/unit/queue_test.cpp create mode 100644 tests/unit/stack_test.cpp diff --git a/include/characters/caravana.hpp b/include/characters/caravana.hpp new file mode 100644 index 0000000..c307943 --- /dev/null +++ b/include/characters/caravana.hpp @@ -0,0 +1,95 @@ +#ifndef CARAVAN_HPP +#define CARAVAN_HPP + +#include "artefactoUnico.hpp" +#include "entidadGenerica.hpp" +#include +#include +#include + +/** + * @class Caravana + * @brief Representa a los comerciantes itinerantes de artefactos únicos. + * + * La caravana viaja por el yermo ofreciendo artículos extremadamente raros a precios elevados. + */ +class Caravana : public EntidadGenerica +{ +private: + std::vector> m_stock; ///< Lista de artefactos únicos disponibles + bool m_confia; ///< Confianza en el refugio + +public: + /** + * @brief Constructor + * @param nombre Nombre de la caravana + * @param confia Indica si la caravana está dispuesta a comerciar + */ + Caravana(const std::string& nombre, bool confia) + : EntidadGenerica(nombre) + , m_confia(confia) + { + inicializarStock(); + } + + /** + * @brief Muestra el inventario de la caravana + */ + void showInfo() const override + { + std::cout << "🚚 Caravana: " << m_name << "\n"; + std::cout << " - Confianza: " << (m_confia ? "Sí" : "No") << "\n"; + std::cout << " - Artefactos disponibles:\n"; + for (const auto& item : m_stock) + { + item->showInfo(); + } + } + + /** + * @brief Intenta comprar un artefacto + * @param nombre Nombre del artefacto + * @return Puntero al artefacto si se realizó la transacción, nullptr en caso contrario + */ + std::shared_ptr comprarArtefacto(const std::string& nombre) + { + if (!m_confia) + { + std::cout << "💬 " << m_name << " >>> No confiamos lo suficiente en tu refugio para hacer negocios." + << std::endl; + return nullptr; + } + + for (auto it = m_stock.begin(); it != m_stock.end(); ++it) + { + // if ((*it)->nombre() == nombre) + // { + // std::cout << "💬 " << m_name << " >>> Excelente elección. Espero que lo uses bien." << std::endl; + // auto item = *it; + // m_stock.erase(it); + // return item; + // } + } + + std::cout << "💬 " << m_name << " >>> No tenemos ese artefacto en este momento." << std::endl; + return nullptr; + } + + /** + * @brief Simula una evaluación de confianza futura + */ + void evaluarConfianza() + { + m_confia = true; // Lógica temporal, puede depender del nivel del refugio + } + +private: + void inicializarStock() + { + // m_stock.emplace_back(std::make_shared("Detector de Radiación", "Herramienta", "Épico", 250.0)); + // m_stock.emplace_back(std::make_shared("Pistola Láser Táctica", "Arma", "Legendaria", 400.0)); + // m_stock.emplace_back(std::make_shared("Batería de Fusión", "Energía", "Rara", 320.0)); + } +}; + +#endif // CARAVAN_HPP diff --git a/include/characters/chracterVisitant.hpp b/include/characters/chracterVisitant.hpp new file mode 100644 index 0000000..022754b --- /dev/null +++ b/include/characters/chracterVisitant.hpp @@ -0,0 +1,51 @@ +// +// Created by gvalenzuela on 3/30/25. +// + +#ifndef CHRACTERVISITANT_HPP +#define CHRACTERVISITANT_HPP + +#include "characters/artefactoUnico.hpp" +#include "characters/asaltante.hpp" +#include "characters/caravana.hpp" +#include "characters/enclave.hpp" +#include "characters/ghoul.hpp" +#include "characters/hermanosDeAcero.hpp" +#include "characters/mercader.hpp" +#include "characters/mercaderAgua.hpp" +#include "characters/mutantes.hpp" +#include "characters/refugiado.hpp" +#include "characters/refugio.hpp" +#include "characters/saqueador.hpp" + +using VisitanteVariant = std::variant< +Refugiado, +Mercader, +MercaderAgua, +Saqueador, +HermanoAcero, +Enclave, +Mutante, +Asaltante, +Ghoul, +Caravana +>; + +namespace NPC { + enum class VisitantCategory + { + REFUGEE, + BROTHER, + ENEMY, + MERCHANT, + CARAVAN + }; + + struct VisitantChance + { + VisitantCategory type; + double weight; + }; +}; + +#endif //CHRACTERVISITANT_HPP diff --git a/include/characters/hermanosDeAcero.hpp b/include/characters/hermanosDeAcero.hpp new file mode 100644 index 0000000..920862c --- /dev/null +++ b/include/characters/hermanosDeAcero.hpp @@ -0,0 +1,94 @@ +#ifndef HERMANO_ACERO_HPP +#define HERMANO_ACERO_HPP + +#include "entidadGenerica.hpp" +#include + +/** + * @class HermanoAcero + * @brief Representa a un miembro de la Hermandad del Acero. + * + * Poseen entrenamiento militar avanzado y pueden usar artefactos únicos. + * Requieren muchos recursos y son estrictos con su permanencia en un refugio. + */ +class HermanoAcero : public EntidadGenerica +{ +private: + int m_entrenamiento; ///< Nivel de entrenamiento (impacta en defensa del refugio) + double m_suministros; ///< Recursos necesarios para mantenerlo + bool m_enRefugio; ///< Si actualmente vive en un refugio + int m_consumoMinimo; ///< Cuántos recursos necesita por turno + +public: + /** + * @brief Constructor + * @param nombre Nombre del miembro + * @param entrenamiento Nivel de habilidad (100 por defecto) + */ + HermanoAcero(const std::string& nombre, int entrenamiento = 100) + : EntidadGenerica(nombre) + , m_entrenamiento(entrenamiento) + , m_suministros(0.20f) // 20% de los suministros del refugio + , m_enRefugio(false) + , m_consumoMinimo(20) // el doble de lo estándar + { + } + + /** + * @brief Muestra información del hermano del acero + */ + void showInfo() const override + { + std::cout << "⚙️ Hermano del Acero: " << m_name << "\n" + << " - Nivel de entrenamiento: " << m_entrenamiento << "\n" + << " - Suministros actuales: " << m_suministros << "\n" + << " - En refugio: " << (m_enRefugio ? "Sí" : "No") << "\n"; + } + + /** + * @brief Intenta ingresar al refugio + * @param recursosDisponibles Recursos disponibles del refugio + * @return Recursos consumidos, o 0 si no fue aceptado + */ + int solicitarIngreso(int recursosDisponibles) + { + if (recursosDisponibles >= m_consumoMinimo) + { + m_enRefugio = true; + std::cout << "💬" << m_name << " >>> Por la tecnología, serviré a este refugio." << std::endl; + return m_consumoMinimo; + } + else + { + std::cout << "💬" << m_name << " >>> Sus recursos no están a la altura de la Hermandad." << std::endl; + return 0; + } + } + + /** + * @brief Consume recursos cada ciclo, si no hay suficientes abandona el refugio + */ + void consumir() + { + if (m_suministros >= m_consumoMinimo) + { + m_suministros -= m_consumoMinimo; + std::cout << "💬" << m_name << " >>> Reabastecido. Listo para defender." << std::endl; + } + else + { + m_enRefugio = false; + std::cout << "💬" << m_name << " >>> Sin suministros. Este refugio no merece protección." << std::endl; + } + } + + /** + * @brief Saber si está aún en el refugio + */ + bool estaEnRefugio() const + { + return m_enRefugio; + } +}; + +#endif // HERMANO_ACERO_HPP diff --git a/include/dataStructures/queue.hpp b/include/dataStructures/queue.hpp new file mode 100644 index 0000000..bef2a29 --- /dev/null +++ b/include/dataStructures/queue.hpp @@ -0,0 +1,119 @@ +#ifndef QUEUE_HPP +#define QUEUE_HPP + +#include + +/** + * @brief Estructura de datos tipo Cola (FIFO - First In, First Out) + * + * @tparam TData Tipo de dato almacenado en la cola + */ +template +class Queue +{ +private: + /** + * @brief Nodo de la cola + */ + struct Node + { + TData data; ///< Dato almacenado + Node* next; ///< Puntero al siguiente nodo + + explicit Node(const TData& value) + : data(value) + , next(nullptr) + { + } + }; + + Node* m_front; ///< Puntero al primer elemento + Node* m_rear; ///< Puntero al último elemento + size_t m_size; ///< Cantidad de elementos en la cola + +public: + /** + * @brief Constructor por defecto + */ + Queue() + : m_front(nullptr) + , m_rear(nullptr) + , m_size(0) + { + } + + /** + * @brief Destructor: libera todos los nodos de la cola + */ + ~Queue() + { + while (!isEmpty()) + { + dequeue(); + } + } + + /** + * @brief Inserta un elemento al final de la cola + * + * @param value Valor a insertar + */ + void enqueue(const TData& value) + { + Node* newNode = new Node(value); + if (isEmpty()) + { + m_front = m_rear = newNode; + } + else + { + m_rear->next = newNode; + m_rear = newNode; + } + ++m_size; + } + + /** + * @brief Elimina el primer elemento de la cola + * + * @throws std::underflow_error si la cola está vacía + */ + void dequeue() + { + throw std::underflow_error("Queue is empty"); + } + + /** + * @brief Devuelve el primer elemento sin eliminarlo + * + * @return TData Primer valor en la cola + * @throws std::underflow_error si la cola está vacía + */ + TData front() const + { + throw std::underflow_error("Queue is empty"); + } + + /** + * @brief Verifica si la cola está vacía + * + * @return true si no hay elementos + * @return false si hay al menos un elemento + */ + bool isEmpty() const + { + return m_size == 0; + } + + /** + * @brief Devuelve la cantidad de elementos en la cola + * + * @return size_t tamaño de la cola + */ + size_t getSize() const + { + return m_size; + } +}; + +#endif // QUEUE_HPP diff --git a/include/dataStructures/stack.hpp b/include/dataStructures/stack.hpp new file mode 100644 index 0000000..fbf5071 --- /dev/null +++ b/include/dataStructures/stack.hpp @@ -0,0 +1,121 @@ +#ifndef STACK_HPP +#define STACK_HPP + +#include + +/** + * @brief Estructura de datos tipo Pila (LIFO - Last In, First Out) + * + * @tparam TData Tipo de dato almacenado en la pila + */ +template +class Stack +{ +private: + /** + * @brief Nodo de la pila + */ + struct Node + { + TData data; ///< Valor almacenado + Node* next; ///< Puntero al siguiente nodo + + Node(const TData& data, Node* next = nullptr) + : data(data) + , next(next) + { + } + }; + + Node* m_top; ///< Puntero al nodo superior (cima) + size_t m_size; ///< Cantidad de elementos en la pila + +public: + /** + * @brief Constructor por defecto + */ + Stack() + : m_top(nullptr) + , m_size(0) + { + } + + /** + * @brief Destructor: libera todos los nodos + */ + ~Stack() + { + throw std::underflow_error("Stack is empty"); + } + + /** + * @brief Agrega un elemento en la cima de la pila + * + * @param value Valor a insertar + */ + void push(const TData& value) + { + Node* newNode = new Node(value, m_top); + m_top = newNode; + ++m_size; + } + + /** + * @brief Elimina el elemento superior de la pila + * + * @throws std::underflow_error si la pila está vacía + */ + void pop() + { + if (isEmpty()) + { + throw std::underflow_error("Stack is empty"); + } + throw std::underflow_error("Stack is empty"); + } + + /** + * @brief Devuelve una referencia al elemento superior (mutable) + * + * @return TData& referencia al valor + * @throws std::underflow_error si la pila está vacía + */ + TData& top() + { + throw std::underflow_error("Stack is empty"); + } + + /** + * @brief Devuelve una referencia constante al elemento superior + * + * @return const TData& referencia constante al valor + * @throws std::underflow_error si la pila está vacía + */ + const TData& top() const + { + throw std::underflow_error("Stack is empty"); + } + + /** + * @brief Verifica si la pila está vacía + * + * @return true si no hay elementos + * @return false si hay al menos un elemento + */ + bool isEmpty() const + { + return m_top == nullptr; + } + + /** + * @brief Devuelve la cantidad de elementos en la pila + * + * @return size_t tamaño de la pila + */ + size_t size() const + { + return m_size; + } +}; + +#endif // STACK_HPP diff --git a/tests/unit/list_test.cpp b/tests/unit/list_test.cpp new file mode 100644 index 0000000..95cb00c --- /dev/null +++ b/tests/unit/list_test.cpp @@ -0,0 +1,70 @@ +#include +#include "list.hpp" + + /**===== BORRAME CUANDO TENGAS TODO LISTO ===== +TEST(LinkedListTest, PushFrontAndPrint) { + LinkedList list; + list.push_front(3); + list.push_front(2); + list.push_front(1); + EXPECT_EQ(list.take(0, 3)->data, 1); +} + +TEST(LinkedListTest, RemoveAt) { + LinkedList list; + list.push_front(3); + list.push_front(2); + list.push_front(1); + list.remove_at(1); + EXPECT_EQ(list.take(0, 2)->next->data, 3); +} + +TEST(LinkedListTest, TakeWithinBounds) { + LinkedList list; + for (int i = 0; i < 5; ++i) + list.push_front(5 - i); + auto newList = list.take(1, 3); + EXPECT_EQ(newList->data, 2); + EXPECT_EQ(newList->next->data, 3); + EXPECT_EQ(newList->next->next->data, 4); +} + +TEST(DoublyLinkedListTest, PushBackAndPrint) { + DoublyLinkedList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + EXPECT_EQ(list.get_head()->data, 1); + EXPECT_EQ(list.get_head()->next->data, 2); + EXPECT_EQ(list.get_head()->next->next->data, 3); +} + +TEST(DoublyLinkedListTest, PushFront) { + DoublyLinkedList list; + list.push_front(1); + list.push_front(2); + EXPECT_EQ(list.get_head()->data, 2); + EXPECT_EQ(list.get_head()->next->data, 1); +} + +TEST(DoublyLinkedListTest, RemoveAt) { + DoublyLinkedList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.remove_at(1); + EXPECT_EQ(list.get_head()->next->data, 3); +} + +TEST(DoublyLinkedListTest, CopyList) { + DoublyLinkedList list1; + list1.push_back(1); + list1.push_back(2); + + DoublyLinkedList list2; + list2.copy_list(list1); + + EXPECT_EQ(list2.get_head()->data, 1); + EXPECT_EQ(list2.get_head()->next->data, 2); +} + ===== BORRAME CUANDO TENGAS TODO LISTO =====*/ \ No newline at end of file diff --git a/tests/unit/queue_test.cpp b/tests/unit/queue_test.cpp new file mode 100644 index 0000000..eac3d0c --- /dev/null +++ b/tests/unit/queue_test.cpp @@ -0,0 +1,36 @@ + +#include +#include "queue.hpp" + +/** ===== BORRAME CUANDO TENGAS TODO LISTO ===== +TEST(QueueTest, EnqueueDequeueFront) { + Queue q; + EXPECT_TRUE(q.isEmpty()); + q.enqueue(10); + q.enqueue(20); + EXPECT_EQ(q.front(), 10); + q.dequeue(); + EXPECT_EQ(q.front(), 20); + q.dequeue(); + EXPECT_TRUE(q.isEmpty()); +} + +TEST(QueueTest, DequeueOnEmptyThrows) { + Queue q; + EXPECT_THROW(q.dequeue(), std::underflow_error); +} + +TEST(QueueTest, FrontOnEmptyThrows) { + Queue q; + EXPECT_THROW(q.front(), std::underflow_error); +} + +TEST(QueueTest, QueueSize) { + Queue q; + q.enqueue("A"); + q.enqueue("B"); + EXPECT_EQ(q.getSize(), 2); + q.dequeue(); + EXPECT_EQ(q.getSize(), 1); +} +===== BORRAME CUANDO TENGAS TODO LISTO ===== */ \ No newline at end of file diff --git a/tests/unit/stack_test.cpp b/tests/unit/stack_test.cpp new file mode 100644 index 0000000..3ebe105 --- /dev/null +++ b/tests/unit/stack_test.cpp @@ -0,0 +1,35 @@ + +#include +#include "stack.hpp" + +/** ===== BORRAME CUANDO TENGAS TODO LISTO ===== +TEST(StackTest, PushPopTop) { + Stack s; + EXPECT_TRUE(s.isEmpty()); + s.push(42); + EXPECT_FALSE(s.isEmpty()); + EXPECT_EQ(s.top(), 42); + s.pop(); + EXPECT_TRUE(s.isEmpty()); +} + +TEST(StackTest, PopOnEmptyThrows) { + Stack s; + EXPECT_THROW(s.pop(), std::underflow_error); +} + +TEST(StackTest, TopOnEmptyThrows) { + Stack s; + EXPECT_THROW(s.top(), std::underflow_error); +} + +TEST(StackTest, StackSize) { + Stack s; + s.push("uno"); + s.push("dos"); + s.push("tres"); + EXPECT_EQ(s.size(), 3); + s.pop(); + EXPECT_EQ(s.size(), 2); +} +===== BORRAME CUANDO TENGAS TODO LISTO ===== */ \ No newline at end of file From 9891acf31d949a63cda588efb5263e2baf7255eb Mon Sep 17 00:00:00 2001 From: NahuelAroca <117319043+NahuelAroca@users.noreply.github.com> Date: Sun, 6 Apr 2025 00:26:34 -0300 Subject: [PATCH 2/5] Update Tarea Se implementaron los metodos faltantes en queue y stack. Se crearon los archivos .cpp de list, queue y stack. --- CMakeLists.txt | 5 +- include/dataStructures/list.cpp | 266 +++++++++++++++++++++++++++++++ include/dataStructures/list.hpp | 252 ++--------------------------- include/dataStructures/queue.cpp | 69 ++++++++ include/dataStructures/queue.hpp | 50 +----- include/dataStructures/stack.cpp | 69 ++++++++ include/dataStructures/stack.hpp | 47 +----- 7 files changed, 437 insertions(+), 321 deletions(-) create mode 100644 include/dataStructures/list.cpp create mode 100644 include/dataStructures/queue.cpp create mode 100644 include/dataStructures/stack.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 49c0947..068b53d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,10 @@ endif() file(GLOB_RECURSE SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp") # Define el ejecutable y sus archivos fuente -add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES}) +add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES} + include/dataStructures/queue.cpp + include/dataStructures/stack.cpp + include/dataStructures/list.cpp) # Establece el directorio de inclusión para los archivos de cabecera usando target_include_directories target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/include") diff --git a/include/dataStructures/list.cpp b/include/dataStructures/list.cpp new file mode 100644 index 0000000..898bbed --- /dev/null +++ b/include/dataStructures/list.cpp @@ -0,0 +1,266 @@ +// +// Created by nahue on 5/4/2025. +// + +#include "list.hpp" + +template +LinkedList::LinkedList() + : head(nullptr) {} + +template +LinkedList::~LinkedList() +{ + while(head != nullptr) + { + auto temporalNode = head; + head = head->next; + delete temporalNode; + } +} + +template +void LinkedList::push_front(const TData& value) +{ + auto nuevo = new ListNode(value); + nuevo->next = head; + head = nuevo; +} + +template +void LinkedList::remove_at(size_t position) +{ + if (head == nullptr) + { + return; + } + + if (position == 0) + { + auto temp = head; + head = head->next; + delete temp; + return; + } + + // Para cualquier otra posicion necesitamos mantener un puntero al nodo anterior + auto prev = head; + auto current = head->next; + size_t current_position = 1; + + // Avanzamos hasta encontrar la posicion o llegar al final de la lista + while (current != nullptr && current_position < position) + { + prev = current; + current = current->next; + current_position++; + } + + // Si current es nullptr quiere decir que la posicion especifica es mas grande que la lista, + // no se encuentra la posicion + if (current == nullptr) return; + + // Hacemos que el nodo anterior apunte al nodo siguiente actual + prev->next = current->next; + + delete current; +} + +template +ListNode* LinkedList::take(size_t startPosition, size_t nElements) +{ + // Si la lista esta vacia retornamos nullptr + if (head == nullptr) + { + return nullptr; + } + + // Buscamos el nodo de inicio + ListNode* current = head; + size_t current_position = 0; + + // Avanzamos hasta la posicion de inicio + while (current != nullptr && current_position < startPosition) + { + current = current->next; + current_position++; + } + + // Si current es nullptr, la posicion esta fuera de rango + if (current == nullptr) return nullptr; + + // Creamos el primer nodo de la nueva lista + ListNode* new_head = new ListNode(current->data); + ListNode* new_current = new_head; + + // Avanzamos al siguiente nodo en la lista original + current = current->next; + + // Copiamos los siguientes mElements-1 nodos (ya copiamos 1) + for (size_t i = 1; i < nElements && current != nullptr; i++) + { + // Creamos un nuevo nodo con el valor actual + new_current->next = new ListNode(current->data); + + // Avanzamos en ambas listas + new_current = new_current->next; + current = current->next; + } + + return new_head; +} + +template +void LinkedList::print() const +{ + ListNode* current = head; + while (current != nullptr) + { + std::cout << current->data << " -> "; + current = current->next; + } + std::cout << "nullptr" << std::endl; +} + +template +DoublyLinkedList::DoublyLinkedList() + : head(nullptr) {} + +template +DoublyLinkedList::~DoublyLinkedList() +{ + while(head != nullptr) + { + auto temporalNode = head; + head = head->next; + delete temporalNode; + } +} + +template +DoublyListNode* DoublyLinkedList::get_head() const +{ + return head; +} + +template +void DoublyLinkedList::push_front(const TData& value) +{ + auto nuevo = new DoublyListNode(value); + nuevo->next = head; + head = nuevo; +} + +template +void DoublyLinkedList::push_back(const TData& value) +{ + auto nuevo = new DoublyListNode(value); + // nuevo->next = nullptr; No haria falta pq cuando se crea un DoublyListNode next y prev se inicilizan en nullptr + + // Si la lista esta vacia + if (!head) + { + head = nuevo; + } + else + { + // Si la lista tiene elementos, recorrer hasta el ultimo nodo + // DoublyListNode* temp = get_head(); + auto temp = get_head(); + while (temp->next != nullptr) // Buscamos el ultimo nodo + { + temp = temp->next; + } + + // temp es el ultimo nodo, se conecta con el nuevo ultimo nodo + temp->next = nuevo; + nuevo->prev = temp; // El prev de nuevo apunta al antiguo ultimo nodo, osea temp + } +} + +template +void DoublyLinkedList::remove_at(size_t position) +{ + // Si la lista esta vacia no hay nada que eliminar + if (head == nullptr) + { + return; + } + + // Caso que el nodo a eliminar sea el primero (nodo 0) + if (position == 0) + { + DoublyListNode* temp = head; + head = head->next; + + // Si hay mas nodos despues del primero actualizamos el prev del nuevo head + if (head != nullptr) + { + head->prev = nullptr; + } + + delete temp; + return; + } + + // Para cualquier otra posicion recorremos la lista, hacemos un contador para llevar track de + // la posicion en la lista + DoublyListNode* current = head; + size_t current_position = 0; + + while (current != nullptr && current_position < position) + { + current = current->next; + current_position++; + } + + // Si current es nullptr quiere decir que la posicion especifica es mas grande que la lista, + // no se encuentra la posicion + if (current == nullptr) return; + + // current es el nodo que queremos eliminar, conectamos sus + // nodos adyacentes + if (current->prev != nullptr) + { + current->prev->next = current->next; + } + + if (current->next != nullptr) + { + current->next->prev = current->prev; + } + + delete current; +} + +template +void DoublyLinkedList::copy_list(const DoublyLinkedList& other) +{ + // PREGUNTAR: Borramos los nodos actuales? + while (head != nullptr) + { + auto temporalNode = head; + head = head->next; + delete temporalNode; + } + + // Copiamos los nodos de la otra lista con push_bakc() + auto current = other.get_head(); + while (current != nullptr) + { + push_back(current->data); + current = current->next; + } +} + +template +void DoublyLinkedList::print() const +{ + DoublyListNode* current = head; + while (current != nullptr) + { + std::cout << current->data << " <-> "; + current = current->next; + } + std::cout << "nullptr" << std::endl; +} \ No newline at end of file diff --git a/include/dataStructures/list.hpp b/include/dataStructures/list.hpp index 469a344..8e0cb77 100644 --- a/include/dataStructures/list.hpp +++ b/include/dataStructures/list.hpp @@ -33,136 +33,34 @@ class LinkedList ListNode* head; public: - LinkedList() - : head(nullptr) - { - } + LinkedList(); - ~LinkedList() - { - while(head != nullptr) - { - auto temporalNode = head; - head = head->next; - delete temporalNode; - } - } + ~LinkedList(); /** * @brief Inserta un nuevo elemento al inicio de la lista * * @param value Valor a insertar */ - void push_front(const TData& value) - { - auto nuevo = new ListNode(value); - nuevo->next = head; - head = nuevo; - } + void push_front(const TData& value); /** * @brief Remueve un elemento de la lista dada su posición * * @param position Posición del elemento a remover */ - void remove_at(size_t position) - { - if (head == nullptr) - { - return; - } - - if (position == 0) - { - auto temp = head; - head = head->next; - delete temp; - return; - } - - // Para cualquier otra posicion necesitamos mantener un puntero al nodo anterior - auto prev = head; - auto current = head->next; - size_t current_position = 1; - - // Avanzamos hasta encontrar la posicion o llegar al final de la lista - while (current != nullptr && current_position < position) - { - prev = current; - current = current->next; - current_position++; - } - - // Si current es nullptr quiere decir que la posicion especifica es mas grande que la lista, - // no se encuentra la posicion - if (current == nullptr) return; - - // Hacemos que el nodo anterior apunte al nodo siguiente actual - prev->next = current->next; - - delete current; - } + void remove_at(size_t position); /** * @brief Crea una lista nueva de n elementos a partir de una posición dada * */ - ListNode* take(size_t startPosition, size_t nElements) - { - // Si la lista esta vacia retornamos nullptr - if (head == nullptr) - { - return nullptr; - } - - // Buscamos el nodo de inicio - ListNode* current = head; - size_t current_position = 0; - - // Avanzamos hasta la posicion de inicio - while (current != nullptr && current_position < startPosition) - { - current = current->next; - current_position++; - } - - // Si current es nullptr, la posicion esta fuera de rango - if (current == nullptr) return nullptr; - - // Creamos el primer nodo de la nueva lista - ListNode* new_head = new ListNode(current->data); - ListNode* new_current = new_head; - - // Avanzamos al siguiente nodo en la lista original - current = current->next; - - // Copiamos los siguientes mElements-1 nodos (ya copiamos 1) - for (size_t i = 1; i < nElements && current != nullptr; i++) - { - // Creamos un nuevo nodo con el valor actual - new_current->next = new ListNode(current->data); - - // Avanzamos en ambas listas - new_current = new_current->next; - current = current->next; - } - - return new_head; - } + ListNode* take(size_t startPosition, size_t nElements); /** * @brief Imprime todos los elementos de la lista */ - void print() const - { - ListNode* current = head; - while (current != nullptr) - { - std::cout << current->data << " -> "; - current = current->next; - } - std::cout << "nullptr" << std::endl; - } + void print() const; }; /** @@ -197,171 +95,49 @@ class DoublyLinkedList DoublyListNode* head; public: - DoublyLinkedList() - : head(nullptr) - { - } + DoublyLinkedList(); - ~DoublyLinkedList() - { - while(head != nullptr) - { - auto temporalNode = head; - head = head->next; - delete temporalNode; - } - } + ~DoublyLinkedList(); /** * @brief Retorna el primer elemento de la lista * * @return Primer elemento de la lista */ - DoublyListNode* get_head() const - { - return head; - } + DoublyListNode* get_head() const; /** * @brief Inserta un nuevo elemento al inicio de la lista * * @param value Valor a insertar */ - void push_front(const TData& value) - { - auto nuevo = new DoublyListNode(value); - nuevo->next = head; - head = nuevo; - } + void push_front(const TData& value); /** * @brief Inserta un nuevo elemento al final de la lista * * @param value Valor a insertar */ - void push_back(const TData& value) - { - auto nuevo = new DoublyListNode(value); - // nuevo->next = nullptr; No haria falta pq cuando se crea un DoublyListNode next y prev se inicilizan en nullptr - - // Si la lista esta vacia - if (!head) - { - head = nuevo; - } - else - { - // Si la lista tiene elementos, recorrer hasta el ultimo nodo - // DoublyListNode* temp = get_head(); - auto temp = get_head(); - while (temp->next != nullptr) // Buscamos el ultimo nodo - { - temp = temp->next; - } - - // temp es el ultimo nodo, se conecta con el nuevo ultimo nodo - temp->next = nuevo; - nuevo->prev = temp; // El prev de nuevo apunta al antiguo ultimo nodo, osea temp - } - } + void push_back(const TData& value); /** * @brief Remueve un elemento de la lista dada su posición * * @param position Posición del elemento a remover */ - void remove_at(size_t position) - { - // Si la lista esta vacia no hay nada que eliminar - if (head == nullptr) - { - return; - } - - // Caso que el nodo a eliminar sea el primero (nodo 0) - if (position == 0) - { - DoublyListNode* temp = head; - head = head->next; - - // Si hay mas nodos despues del primero actualizamos el prev del nuevo head - if (head != nullptr) - { - head->prev = nullptr; - } - - delete temp; - return; - } - - // Para cualquier otra posicion recorremos la lista, hacemos un contador para llevar track de - // la posicion en la lista - DoublyListNode* current = head; - size_t current_position = 0; - - while (current != nullptr && current_position < position) - { - current = current->next; - current_position++; - } - - // Si current es nullptr quiere decir que la posicion especifica es mas grande que la lista, - // no se encuentra la posicion - if (current == nullptr) return; - - // current es el nodo que queremos eliminar, conectamos sus - // nodos adyacentes - if (current->prev != nullptr) - { - current->prev->next = current->next; - } - - if (current->next != nullptr) - { - current->next->prev = current->prev; - } - - delete current; - - } + void remove_at(size_t position); /** * @brief Copia los elementos de otra lista * * @param other Lista de la cual copiar los elementos */ - void copy_list(const DoublyLinkedList& other) - { - // PREGUNTAR: Borramos los nodos actuales? - while (head != nullptr) - { - auto temporalNode = head; - head = head->next; - delete temporalNode; - } - - // Copiamos los nodos de la otra lista con push_bakc() - auto current = other.get_head(); - while (current != nullptr) - { - push_back(current->data); - current = current->next; - } - } + void copy_list(const DoublyLinkedList& other); /** * @brief Imprime todos los elementos de la lista */ - void print() const - { - DoublyListNode* current = head; - while (current != nullptr) - { - std::cout << current->data << " <-> "; - current = current->next; - } - std::cout << "nullptr" << std::endl; - } + void print() const; }; #endif // LIST_HPP diff --git a/include/dataStructures/queue.cpp b/include/dataStructures/queue.cpp new file mode 100644 index 0000000..8ee14f6 --- /dev/null +++ b/include/dataStructures/queue.cpp @@ -0,0 +1,69 @@ +// +// Created by nahue on 5/4/2025. +// + +#include "queue.hpp" + +template +Queue::Queue() + : m_front(nullptr), m_rear(nullptr), m_size(0) {} + +template +Queue::~Queue() +{ + while (!isEmpty()) + { + dequeue(); + } +} + +template +void Queue::enqueue(const TData& value) +{ + Node* newNode = new Node(value); + if (isEmpty()) + { + m_front = m_rear = newNode; + } + else + { + m_rear->next = newNode; + m_rear = newNode; + } + ++m_size; +} + +template +void Queue::dequeue() +{ + if (isEmpty()){ + throw std::underflow_error("Queue is empty"); + } + + Node* temp = m_front; + m_front = m_front->next; + --m_size; + delete temp; +} + +template +TData Queue::front() const +{ + if (isEmpty()){ + throw std::underflow_error("Queue is empty"); + } + + return m_front->data; +} + +template +bool Queue::isEmpty() const +{ + return m_size == 0; +} + +template +size_t Queue::getSize() const +{ + return m_size; +} diff --git a/include/dataStructures/queue.hpp b/include/dataStructures/queue.hpp index bef2a29..6c22edf 100644 --- a/include/dataStructures/queue.hpp +++ b/include/dataStructures/queue.hpp @@ -35,53 +35,26 @@ class Queue /** * @brief Constructor por defecto */ - Queue() - : m_front(nullptr) - , m_rear(nullptr) - , m_size(0) - { - } + Queue(); /** * @brief Destructor: libera todos los nodos de la cola */ - ~Queue() - { - while (!isEmpty()) - { - dequeue(); - } - } + ~Queue(); /** * @brief Inserta un elemento al final de la cola * * @param value Valor a insertar */ - void enqueue(const TData& value) - { - Node* newNode = new Node(value); - if (isEmpty()) - { - m_front = m_rear = newNode; - } - else - { - m_rear->next = newNode; - m_rear = newNode; - } - ++m_size; - } + void enqueue(const TData& value); /** * @brief Elimina el primer elemento de la cola * * @throws std::underflow_error si la cola está vacía */ - void dequeue() - { - throw std::underflow_error("Queue is empty"); - } + void dequeue(); /** * @brief Devuelve el primer elemento sin eliminarlo @@ -89,10 +62,7 @@ class Queue * @return TData Primer valor en la cola * @throws std::underflow_error si la cola está vacía */ - TData front() const - { - throw std::underflow_error("Queue is empty"); - } + TData front() const; /** * @brief Verifica si la cola está vacía @@ -100,20 +70,14 @@ class Queue * @return true si no hay elementos * @return false si hay al menos un elemento */ - bool isEmpty() const - { - return m_size == 0; - } + bool isEmpty() const; /** * @brief Devuelve la cantidad de elementos en la cola * * @return size_t tamaño de la cola */ - size_t getSize() const - { - return m_size; - } + size_t getSize() const; }; #endif // QUEUE_HPP diff --git a/include/dataStructures/stack.cpp b/include/dataStructures/stack.cpp new file mode 100644 index 0000000..c44297c --- /dev/null +++ b/include/dataStructures/stack.cpp @@ -0,0 +1,69 @@ +// +// Created by nahue on 5/4/2025. +// + +#include "stack.hpp" + +template +Stack::Stack() + : m_top(nullptr), m_size(0) {} + +template +Stack::~Stack() +{ + while(isEmpty()){ + pop(); + } +} + +template +void Stack::push(const TData& value) +{ + Node* newNode = new Node(value, m_top); + m_top = newNode; + ++m_size; +} + +template +void Stack::pop() +{ + if (isEmpty()) + { + throw std::underflow_error("Stack is empty"); + } + + auto newNode = m_top; + m_top = m_top->next; + --m_size; + delete newNode; +} + +template +TData& Stack::top() +{ + if (isEmpty()){ + throw std::underflow_error("Stack is empty"); + } + return m_top->data; +} + +template +const TData& Stack::top() const +{ + if (isEmpty()){ + throw std::underflow_error("Stack is empty"); + } + return m_top->data; +} + +template +bool Stack::isEmpty() const +{ + return m_top == nullptr; +} + +template +size_t Stack::size() const +{ + return m_size; +} \ No newline at end of file diff --git a/include/dataStructures/stack.hpp b/include/dataStructures/stack.hpp index fbf5071..c121f25 100644 --- a/include/dataStructures/stack.hpp +++ b/include/dataStructures/stack.hpp @@ -34,45 +34,26 @@ class Stack /** * @brief Constructor por defecto */ - Stack() - : m_top(nullptr) - , m_size(0) - { - } + Stack(); /** * @brief Destructor: libera todos los nodos */ - ~Stack() - { - throw std::underflow_error("Stack is empty"); - } + ~Stack(); /** * @brief Agrega un elemento en la cima de la pila * * @param value Valor a insertar */ - void push(const TData& value) - { - Node* newNode = new Node(value, m_top); - m_top = newNode; - ++m_size; - } + void push(const TData& value); /** * @brief Elimina el elemento superior de la pila * * @throws std::underflow_error si la pila está vacía */ - void pop() - { - if (isEmpty()) - { - throw std::underflow_error("Stack is empty"); - } - throw std::underflow_error("Stack is empty"); - } + void pop(); /** * @brief Devuelve una referencia al elemento superior (mutable) @@ -80,10 +61,7 @@ class Stack * @return TData& referencia al valor * @throws std::underflow_error si la pila está vacía */ - TData& top() - { - throw std::underflow_error("Stack is empty"); - } + TData& top(); /** * @brief Devuelve una referencia constante al elemento superior @@ -91,10 +69,7 @@ class Stack * @return const TData& referencia constante al valor * @throws std::underflow_error si la pila está vacía */ - const TData& top() const - { - throw std::underflow_error("Stack is empty"); - } + const TData& top() const; /** * @brief Verifica si la pila está vacía @@ -102,20 +77,14 @@ class Stack * @return true si no hay elementos * @return false si hay al menos un elemento */ - bool isEmpty() const - { - return m_top == nullptr; - } + bool isEmpty() const; /** * @brief Devuelve la cantidad de elementos en la pila * * @return size_t tamaño de la pila */ - size_t size() const - { - return m_size; - } + size_t size() const; }; #endif // STACK_HPP From 0b628abeb50496855f3c944a843c2d5eda97ecb4 Mon Sep 17 00:00:00 2001 From: NahuelAroca <117319043+NahuelAroca@users.noreply.github.com> Date: Mon, 7 Apr 2025 20:45:49 -0300 Subject: [PATCH 3/5] Update Tarea Se implementaron metodos print() en queue y stack, tambien metodos registerDecision y onNewEvent en clase Engine. Se agregaron comandos de consola para CHECK_EVENT, SHO_EVENT y SHOW_HISTORY. Se creo un struct Event para registrar los eventos del jugador. --- CMakeLists.txt | 7 ++++--- include/dataStructures/queue.hpp | 2 ++ include/dataStructures/stack.hpp | 2 ++ include/engine.hpp | 10 ++++++++++ include/event.h | 21 +++++++++++++++++++++ src/engine.cpp | 23 +++++++++++++++++++++++ {include/dataStructures => src}/list.cpp | 2 +- {include/dataStructures => src}/queue.cpp | 18 +++++++++++++++++- {include/dataStructures => src}/stack.cpp | 18 ++++++++++++++++-- tests/unit/list_test.cpp | 4 +--- tests/unit/queue_test.cpp | 5 ++--- tests/unit/stack_test.cpp | 4 +--- 12 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 include/event.h rename {include/dataStructures => src}/list.cpp (99%) rename {include/dataStructures => src}/queue.cpp (79%) rename {include/dataStructures => src}/stack.cpp (79%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 068b53d..8ae2528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,10 @@ file(GLOB_RECURSE SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp") # Define el ejecutable y sus archivos fuente add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES} - include/dataStructures/queue.cpp - include/dataStructures/stack.cpp - include/dataStructures/list.cpp) + src/queue.cpp + src/stack.cpp + src/list.cpp + include/event.h) # Establece el directorio de inclusión para los archivos de cabecera usando target_include_directories target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/include") diff --git a/include/dataStructures/queue.hpp b/include/dataStructures/queue.hpp index 6c22edf..c0ffe43 100644 --- a/include/dataStructures/queue.hpp +++ b/include/dataStructures/queue.hpp @@ -78,6 +78,8 @@ class Queue * @return size_t tamaño de la cola */ size_t getSize() const; + + void print() const; }; #endif // QUEUE_HPP diff --git a/include/dataStructures/stack.hpp b/include/dataStructures/stack.hpp index c121f25..05acab4 100644 --- a/include/dataStructures/stack.hpp +++ b/include/dataStructures/stack.hpp @@ -85,6 +85,8 @@ class Stack * @return size_t tamaño de la pila */ size_t size() const; + + void print() const; }; #endif // STACK_HPP diff --git a/include/engine.hpp b/include/engine.hpp index 1101f90..e7762e6 100644 --- a/include/engine.hpp +++ b/include/engine.hpp @@ -5,6 +5,9 @@ #include "randomEventGenerator.hpp" #include "refugio.hpp" #include "engineData.hpp" +#include "event.h" +#include "queue.hpp" +#include "stack.hpp" #include #include #include @@ -122,10 +125,16 @@ class Engine */ void loadConfig(); + void onNewEvent(const Event& evento); + + void registerDecision(const std::string& accion); + EngineData::PlayerInfo m_player; //< Información del jugador RandomEventGenerator m_randomGenerator; //< Generador de eventos aleatorios EngineData::GameConfig m_gameConfig; //< Configuración del juego std::unique_ptr m_shelter; //< Refugio del jugador + Queue m_eventosPendientes; + Stack m_historialDecisiones; /** * @brief: Operaciones que puede realizar el jugador @@ -135,6 +144,7 @@ class Engine SHOW_STATUS, //< Muestra el estado actual del refugio SHOW_EVENTS, //< Muestra los eventos aleatorios CHECK_EVENT, //< Muestra el evento actual + SHOW_HISTORY, // + +struct Event +{ + std::string m_type; //tipo de evento + std::string m_description; //descripcion del evento + std::string m_time; //ticks que durara el evento + + Event(std::string type, std::string description, std::string time) + : m_type(std::move(type)), m_description(std::move(description)), m_time(std::move(time)) {} + +}; + +#endif //EVENT_H diff --git a/src/engine.cpp b/src/engine.cpp index d66bbc3..1177c64 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -150,6 +150,18 @@ void Engine::interactiveConsole() std::cout << "Mostrando detalles..." << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); break; + case Operation::SHOW_EVENTS: + std::cout<<"Mostrando eventos pendientes..."<< std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + m_eventosPendientes.print(); + case Operation::CHECK_EVENT: + std::cout<<"Mostrando evento actual..."<< std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + std::cout< LinkedList::LinkedList() diff --git a/include/dataStructures/queue.cpp b/src/queue.cpp similarity index 79% rename from include/dataStructures/queue.cpp rename to src/queue.cpp index 8ee14f6..54f53df 100644 --- a/include/dataStructures/queue.cpp +++ b/src/queue.cpp @@ -2,7 +2,9 @@ // Created by nahue on 5/4/2025. // -#include "queue.hpp" +#include "../include/dataStructures/queue.hpp" + +#include template Queue::Queue() @@ -67,3 +69,17 @@ size_t Queue::getSize() const { return m_size; } + +template +void Queue::print() const +{ + Node* temp = m_front; + while (temp != nullptr) + { + std::cout << temp->data << " "; + temp = temp->next; + } + delete temp; +} + + diff --git a/include/dataStructures/stack.cpp b/src/stack.cpp similarity index 79% rename from include/dataStructures/stack.cpp rename to src/stack.cpp index c44297c..0aca7a6 100644 --- a/include/dataStructures/stack.cpp +++ b/src/stack.cpp @@ -2,7 +2,9 @@ // Created by nahue on 5/4/2025. // -#include "stack.hpp" +#include "../include/dataStructures/stack.hpp" + +#include template Stack::Stack() @@ -66,4 +68,16 @@ template size_t Stack::size() const { return m_size; -} \ No newline at end of file +} + +template +void Stack::print() const +{ + auto temp = m_top; + while(temp != nullptr) + { + std::cout << temp->data << " "; + temp = temp->next; + } + delete temp; +} diff --git a/tests/unit/list_test.cpp b/tests/unit/list_test.cpp index 95cb00c..374349a 100644 --- a/tests/unit/list_test.cpp +++ b/tests/unit/list_test.cpp @@ -1,7 +1,6 @@ #include #include "list.hpp" - /**===== BORRAME CUANDO TENGAS TODO LISTO ===== TEST(LinkedListTest, PushFrontAndPrint) { LinkedList list; list.push_front(3); @@ -66,5 +65,4 @@ TEST(DoublyLinkedListTest, CopyList) { EXPECT_EQ(list2.get_head()->data, 1); EXPECT_EQ(list2.get_head()->next->data, 2); -} - ===== BORRAME CUANDO TENGAS TODO LISTO =====*/ \ No newline at end of file +} \ No newline at end of file diff --git a/tests/unit/queue_test.cpp b/tests/unit/queue_test.cpp index eac3d0c..611891f 100644 --- a/tests/unit/queue_test.cpp +++ b/tests/unit/queue_test.cpp @@ -2,7 +2,7 @@ #include #include "queue.hpp" -/** ===== BORRAME CUANDO TENGAS TODO LISTO ===== + TEST(QueueTest, EnqueueDequeueFront) { Queue q; EXPECT_TRUE(q.isEmpty()); @@ -32,5 +32,4 @@ TEST(QueueTest, QueueSize) { EXPECT_EQ(q.getSize(), 2); q.dequeue(); EXPECT_EQ(q.getSize(), 1); -} -===== BORRAME CUANDO TENGAS TODO LISTO ===== */ \ No newline at end of file +} \ No newline at end of file diff --git a/tests/unit/stack_test.cpp b/tests/unit/stack_test.cpp index 3ebe105..c6d463d 100644 --- a/tests/unit/stack_test.cpp +++ b/tests/unit/stack_test.cpp @@ -2,7 +2,6 @@ #include #include "stack.hpp" -/** ===== BORRAME CUANDO TENGAS TODO LISTO ===== TEST(StackTest, PushPopTop) { Stack s; EXPECT_TRUE(s.isEmpty()); @@ -31,5 +30,4 @@ TEST(StackTest, StackSize) { EXPECT_EQ(s.size(), 3); s.pop(); EXPECT_EQ(s.size(), 2); -} -===== BORRAME CUANDO TENGAS TODO LISTO ===== */ \ No newline at end of file +} \ No newline at end of file From f49135204c3c50030e5f4cbddf67ed37c5450cf8 Mon Sep 17 00:00:00 2001 From: NahuelAroca <117319043+NahuelAroca@users.noreply.github.com> Date: Mon, 7 Apr 2025 21:10:48 -0300 Subject: [PATCH 4/5] Update Tarea Correccion en metodos print de Queue y Stack. --- src/queue.cpp | 1 - src/stack.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/queue.cpp b/src/queue.cpp index 54f53df..f75a2e6 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -79,7 +79,6 @@ void Queue::print() const std::cout << temp->data << " "; temp = temp->next; } - delete temp; } diff --git a/src/stack.cpp b/src/stack.cpp index 0aca7a6..4bfec1a 100644 --- a/src/stack.cpp +++ b/src/stack.cpp @@ -79,5 +79,4 @@ void Stack::print() const std::cout << temp->data << " "; temp = temp->next; } - delete temp; } From f3823a8f0211e8532bd9f0e21cd7a7d4a5acc1d2 Mon Sep 17 00:00:00 2001 From: NahuelAroca <117319043+NahuelAroca@users.noreply.github.com> Date: Mon, 7 Apr 2025 22:16:21 -0300 Subject: [PATCH 5/5] Correccion compilacion. Me ayudo chatgpt por que iba mas alla de mis conocimientos pero habian problemas de linkeo cuando se creaba un Queue con Event y un List con Refugiado. Tambien daba problemas al tratarlos de imprimir por pantalla, ya que la funcion print() de Queue realizaba un cout << temp->data pero al estar apuntando a un Event no sabia como resolverlo. --- include/characters/refugio.hpp | 4 ++++ include/dataStructures/queue.hpp | 2 ++ include/dataStructures/stack.hpp | 1 + include/event.h | 5 +++++ src/list.cpp | 3 +++ src/queue.cpp | 4 +++- src/refugio.cpp | 24 ++++++++++++++++++++++++ src/stack.cpp | 2 ++ 8 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/characters/refugio.hpp b/include/characters/refugio.hpp index e534a7d..7d1e9de 100644 --- a/include/characters/refugio.hpp +++ b/include/characters/refugio.hpp @@ -30,6 +30,8 @@ class Refugio : public EntidadGenerica { std::string nombre; EngineData::Faction faccion; + + friend std::ostream& operator<<(std::ostream& os, const Visitante& visitante); }; private: @@ -48,6 +50,8 @@ class Refugio : public EntidadGenerica */ std::string faccionToString(EngineData::Faction faccion) const; + friend std::ostream& operator<<(std::ostream& os, const Visitante& visitante); + public: /** * @brief Constructor del refugio diff --git a/include/dataStructures/queue.hpp b/include/dataStructures/queue.hpp index c0ffe43..d34de8d 100644 --- a/include/dataStructures/queue.hpp +++ b/include/dataStructures/queue.hpp @@ -8,6 +8,7 @@ * * @tparam TData Tipo de dato almacenado en la cola */ + template class Queue { @@ -82,4 +83,5 @@ class Queue void print() const; }; + #endif // QUEUE_HPP diff --git a/include/dataStructures/stack.hpp b/include/dataStructures/stack.hpp index 05acab4..3dfdd48 100644 --- a/include/dataStructures/stack.hpp +++ b/include/dataStructures/stack.hpp @@ -89,4 +89,5 @@ class Stack void print() const; }; + #endif // STACK_HPP diff --git a/include/event.h b/include/event.h index 28a8c41..848e140 100644 --- a/include/event.h +++ b/include/event.h @@ -16,6 +16,11 @@ struct Event Event(std::string type, std::string description, std::string time) : m_type(std::move(type)), m_description(std::move(description)), m_time(std::move(time)) {} + friend std::ostream& operator<<(std::ostream& os, const Event& event) + { + os << "Tipo: " << event.m_type << ", Descripción: " << event.m_description << ", Tiempo: " << event.m_time; + return os; + } }; #endif //EVENT_H diff --git a/src/list.cpp b/src/list.cpp index 1a5b297..9ba0adf 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -3,6 +3,9 @@ // #include "../include/dataStructures/list.hpp" +#include "refugio.hpp" + +template class DoublyLinkedList; template LinkedList::LinkedList() diff --git a/src/queue.cpp b/src/queue.cpp index f75a2e6..9f2b763 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -3,9 +3,11 @@ // #include "../include/dataStructures/queue.hpp" - +#include #include +template class Queue; // Instancia específica + template Queue::Queue() : m_front(nullptr), m_rear(nullptr), m_size(0) {} diff --git a/src/refugio.cpp b/src/refugio.cpp index 39258be..ea34bbd 100644 --- a/src/refugio.cpp +++ b/src/refugio.cpp @@ -1,5 +1,20 @@ #include "refugio.hpp" +std::string Refugio::faccionToString(EngineData::Faction faccion) const +{ + switch (faccion) + { + case EngineData::Faction::REFUGEES: return "Refugiados"; + case EngineData::Faction::WATER_MERCHANTS: return "Comerciantes de Agua"; + case EngineData::Faction::MERCHANTS: return "Comerciantes"; + case EngineData::Faction::STEEL_BROTHERS: return "Hermanos del Acero"; + case EngineData::Faction::CARAVAN: return "Caravana"; + case EngineData::Faction::RAIDERS: return "Asaltantes"; + case EngineData::Faction::MUTANTS: return "Mutantes"; + default: return "Desconocida"; + } +} + Refugio::Refugio(const std::string& name, const std::string& leader) : EntidadGenerica(name) , m_leader(leader) @@ -77,3 +92,12 @@ bool Refugio::isSafeFaction(const EngineData::Faction faccion) const faccion == EngineData::Faction::MERCHANTS || faccion == EngineData::Faction::STEEL_BROTHERS || faccion == EngineData::Faction::CARAVAN); } + +std::ostream& operator<<(std::ostream& os, const Refugio::Visitante& visitante) +{ + // Creamos una instancia temporal para llamar a faccionToString (ya que no es static) + Refugio dummy("Dummy", "Líder"); + os << visitante.nombre << " (" << dummy.faccionToString(visitante.faccion) << ")"; + return os; +} + diff --git a/src/stack.cpp b/src/stack.cpp index 4bfec1a..912d350 100644 --- a/src/stack.cpp +++ b/src/stack.cpp @@ -6,6 +6,8 @@ #include +template class Stack; + template Stack::Stack() : m_top(nullptr), m_size(0) {}