Implementación de Puertas Lógicas en C++

Puerta.hpp

#ifndef _PUERTA_
#define _PUERTA_

#include <iostream>
#include <sstream>
#include <string>

class Puerta {
protected:
    static int contador;
    int getId;

public:
    static const int CERO = 0;
    static const int UNO = 1;
    static const int ND = 9;

    friend std::ostream& operator<<(std::ostream& o, Puerta& p);

    Puerta();
    virtual int salida() = 0;
    virtual std::string tipo() = 0;
    virtual std::string toString(int numEsp = 0);
};

#endif

Puerta.cpp

#include <iostream>
#include <sstream>
#include "Puerta.hpp"

Puerta::Puerta() {
    this->getId = contador;
    contador++;
}

std::string Puerta::toString(int numEsp) {
    std::stringstream o; // cadena de caracteres
    std::string espacios(numEsp, ' ');
    o << espacios << tipo() << " id=" << this->getId;
    o << " salida=" << salida() << std::endl;
    o << toString(numEsp + 2); // Llamada recursiva corregida
    return o.str();
}

std::ostream& operator<<(std::ostream& o, Puerta& p) {
    o << p.toString();
    return o;
}

int Puerta::contador = 2;

Not.hpp

#ifndef _NOT_
#define _NOT_

#include "Puerta1E.hpp" // Inclusión corregida

class Not : public Puerta1E {
public:
    Not();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

Not.cpp

#include "Not.hpp"

Not::Not() {
    this->entrada1 = nullptr;
}

int Not::salida() {
    if (this->entrada1 != nullptr) {
        int resultado = this->entrada1->salida();

        if (resultado == UNO) {
            return CERO;
        }
        if (resultado == CERO) {
            return UNO;
        }

        if (resultado == ND) {
            return ND;
        }
    } else {
        return ND;
    }
}

std::string Not::tipo() {
    return "NOT";
}

std::string Not::toString(int numEsp) {
    std::string espacios(numEsp, ' ');
    if (this->entrada1 != nullptr) {
        return this->entrada1->toString(numEsp); // Retorno corregido
    } else {
        return espacios + "NO CONECTADA";
    }
}

Puerta2E.hpp

#ifndef _PUERTA2E_
#define _PUERTA2E_

#include <vector> // Inclusión para std::vector
#include "Puerta.hpp"

class Puerta2E : public Puerta {
protected:
    Puerta* Entrada1; // Se mantiene Entrada1 para compatibilidad con código anterior
    // Puerta *Entrada2; // Eliminado para usar std::vector
    std::vector<Puerta*> Entradas; // Vector para múltiples entradas

public:
    Puerta2E();
    virtual int salida() = 0;
    virtual std::string tipo() = 0;
    virtual std::string toString(int numEsp = 0);
    void conecta1(Puerta* pt); // Se mantiene conecta1 para compatibilidad
    void conecta2(Puerta* pt); // Se mantiene conecta2 para compatibilidad
    void conecta(Puerta* pt); // Nueva función para conectar múltiples entradas
};

#endif

Puerta2E.cpp

#include "Puerta2E.hpp"

Puerta2E::Puerta2E() {

}

void Puerta2E::conecta1(Puerta* pt) {
    this->Entrada1 = pt;
}

void Puerta2E::conecta2(Puerta* pt) {
    // this->Entrada2 = pt; // Eliminado para usar std::vector
    this->Entradas.push_back(pt); // Se agrega al vector de entradas
}

void Puerta2E::conecta(Puerta* pt) {
    this->Entradas.push_back(pt);
}

Fijo.hpp

#ifndef _FIJO_
#define _FIJO_

#include "Puerta0E.hpp"

class Fijo : public Puerta0E {
private:
    int estado;

public:
    Fijo();
    void pon0();
    void pon1();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

Fijo.cpp

#include "Fijo.hpp"

Fijo::Fijo() {
    this->estado = ND;
}

int Fijo::salida() {
    return this->estado;
}

std::string Fijo::tipo() {
    return "FIJO";
}

std::string Fijo::toString(int numEsp) {
    return ""; // Retorna una cadena vacía si no se necesita mostrar nada específico
}

void Fijo::pon0() {
    this->estado = CERO;
}

void Fijo::pon1() {
    this->estado = UNO;
}

Uno.hpp

#ifndef _UNO_
#define _UNO_

#include "Puerta0E.hpp"

class Uno : public Puerta0E {
public:
    Uno();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

Uno.cpp

#include "Uno.hpp"

Uno::Uno() {

}

int Uno::salida() {
    return UNO;
}

std::string Uno::tipo() {
    return "UNO";
}

std::string Uno::toString(int numEsp) {
    return ""; // Retorna una cadena vacía si no se necesita mostrar nada específico
}

And.hpp

#ifndef _AND_
#define _AND_

#include "Puerta2E.hpp"

class And : public Puerta2E {
public:
    And();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

And.cpp

#include "And.hpp"

And::And() {
    this->entrada1 = nullptr;
    this->entrada2 = nullptr; // Inicialización para compatibilidad
}

int And::salida() {
    if (this->entrada1 == nullptr || this->Entradas.empty()) { // Verificación de entradas
        return ND;
    }

    int e1 = this->entrada1->salida(); // Salida de la primera entrada (para compatibilidad)
    // int e2 = this->entrada2->salida(); // Eliminado para usar std::vector

    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p->salida() == ND || e1 == ND) {
            return ND;
        }
        if (p->salida() == CERO || e1 == CERO) {
            return CERO; // Si alguna entrada es CERO, la salida es CERO
        }
    }

    return UNO; // Si todas las entradas son UNO, la salida es UNO
}

std::string And::tipo() {
    return "AND";
}

std::string And::toString(int numEsp) {
    std::string resultado;
    std::string espacios(numEsp, ' ');
    if (this->entrada1 != nullptr) {
        resultado = this->entrada1->toString(numEsp);
    } else {
        resultado = espacios + "NO CONECTADA\n";
    }
    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p != nullptr) {
            resultado = resultado + p->toString(numEsp); // Concatenar la representación de cada entrada
        } else {
            resultado = resultado + espacios + "NO CONECTADA\n";
        }
    }
    return resultado;
}

Or.hpp

#ifndef _OR_
#define _OR_

#include "Puerta2E.hpp"

class Or : public Puerta2E {
public:
    Or();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

Or.cpp

#include "Or.hpp"

Or::Or() {
    this->entrada1 = nullptr;
    this->entrada2 = nullptr; // Inicialización para compatibilidad
}

int Or::salida() {
    if (this->entrada1 == nullptr || this->Entradas.empty()) { // Verificación de entradas
        return ND;
    }

    int e1 = this->entrada1->salida(); // Salida de la primera entrada (para compatibilidad)
    // int e2 = this->entrada2->salida(); // Eliminado para usar std::vector

    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p->salida() == ND || e1 == ND) {
            return ND;
        }
        if (p->salida() == UNO || e1 == UNO) {
            return UNO; // Si alguna entrada es UNO, la salida es UNO
        }
    }

    return CERO; // Si todas las entradas son CERO, la salida es CERO
}

std::string Or::tipo() {
    return "OR";
}

std::string Or::toString(int numEsp) {
    std::string resultado;
    std::string espacios(numEsp, ' ');
    if (this->entrada1 != nullptr) {
        resultado = this->entrada1->toString(numEsp);
    } else {
        resultado = espacios + "NO CONECTADA\n";
    }
    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p != nullptr) {
            resultado = resultado + p->toString(numEsp); // Concatenar la representación de cada entrada
        } else {
            resultado = resultado + espacios + "NO CONECTADA\n";
        }
    }
    return resultado;
}

Xor.hpp

#ifndef _XOR_
#define _XOR_

#include "Puerta2E.hpp"

class Xor : public Puerta2E {
public:
    Xor();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

Xor.cpp

#include "Xor.hpp"

Xor::Xor() {
    this->entrada1 = nullptr;
    this->entrada2 = nullptr; // Inicialización para compatibilidad
}

int Xor::salida() {
    if (this->entrada1 == nullptr || this->Entradas.empty()) { // Verificación de entradas
        return ND;
    }

    int e1 = this->entrada1->salida(); // Salida de la primera entrada (para compatibilidad)
    // int e2 = this->entrada2->salida(); // Eliminado para usar std::vector

    bool hayUno = false; // Bandera para indicar si hay al menos un UNO

    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p->salida() == ND || e1 == ND) {
            return ND;
        }
        if (p->salida() == UNO || e1 == UNO) {
            hayUno = !hayUno; // Cambiar el estado de la bandera si se encuentra un UNO
        }
    }

    return hayUno ? UNO : CERO; // Si hay un número impar de UNO, la salida es UNO, de lo contrario es CERO
}

std::string Xor::tipo() {
    return "XOR";
}

std::string Xor::toString(int numEsp) {
    std::string resultado;
    std::string espacios(numEsp, ' ');
    if (this->entrada1 != nullptr) {
        resultado = this->entrada1->toString(numEsp);
    } else {
        resultado = espacios + "NO CONECTADA\n";
    }
    for (Puerta* p : this->Entradas) { // Iterar sobre las entradas en el vector
        if (p != nullptr) {
            resultado = resultado + p->toString(numEsp); // Concatenar la representación de cada entrada
        } else {
            resultado = resultado + espacios + "NO CONECTADA\n";
        }
    }
    return resultado;
}

AndM.hpp

#ifndef _ANDM_
#define _ANDM_

#include "PuertaME.hpp" // Inclusión corregida

class AndM : public PuertaME {
public:
    AndM();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

AndM.cpp

#include "AndM.hpp"
#include "Puerta.hpp"

AndM::AndM() {
}

int AndM::salida() {
    for (Puerta* p : this->Entradas) {
        if (p == nullptr) {
            return ND;
        }
    }
    for (Puerta* p : this->Entradas) {
        if (p->salida() == ND) {
            return ND;
        }
    }
    for (Puerta* p : this->Entradas) {
        if (p->salida() == CERO) {
            return CERO; // Si alguna entrada es CERO, la salida es CERO
        }
    }
    return UNO; // Si todas las entradas son UNO, la salida es UNO
}

std::string AndM::tipo() {
    return "ANDM";
}

std::string AndM::toString(int numEsp) {
    std::string resultado;
    for (Puerta* p : this->Entradas) {
        if (p != nullptr) resultado += p->toString(numEsp); // Concatenar la representación de cada entrada con el número de espacios adecuado
    }
    return resultado;
}

OrM.hpp

#ifndef _ORM_
#define _ORM_

#include "PuertaME.hpp" // Inclusión corregida

class OrM : public PuertaME {
public:
    OrM();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

OrM.cpp

#include "OrM.hpp"
#include "Puerta.hpp"

OrM::OrM() {
}

int OrM::salida() {
    for (Puerta* p : this->Entradas) {
        if (p == nullptr) {
            return ND;
        }
    }
    for (Puerta* p : this->Entradas) {
        if (p->salida() == ND) {
            return ND;
        }
    }
    for (Puerta* p : this->Entradas) {
        if (p->salida() == UNO) {
            return UNO; // Si alguna entrada es UNO, la salida es UNO
        }
    }
    return CERO; // Si todas las entradas son CERO, la salida es CERO
}

std::string OrM::tipo() {
    return "ORM";
}

std::string OrM::toString(int numEsp) {
    std::string resultado;
    for (Puerta* p : this->Entradas) {
        if (p != nullptr) resultado += p->toString(numEsp); // Concatenar la representación de cada entrada con el número de espacios adecuado
    }
    return resultado;
}

XorM.hpp

#ifndef _XORM_
#define _XORM_

#include "PuertaME.hpp" // Inclusión corregida

class XorM : public PuertaME {
public:
    XorM();
    int salida();
    std::string tipo();
    std::string toString(int numEsp);
};

#endif

XorM.cpp

#include "XorM.hpp"
#include "Puerta.hpp"

XorM::XorM() {
}

int XorM::salida() {
    for (Puerta* p : this->Entradas) {
        if (p == nullptr) {
            return ND;
        }
    }
    for (Puerta* p : this->Entradas) {
        if (p->salida() == ND) {
            return ND;
        }
    }

    bool hayUno = false; // Bandera para indicar si hay al menos un UNO

    for (Puerta* p : this->Entradas) {
        if (p->salida() == UNO) {
            hayUno = !hayUno; // Cambiar el estado de la bandera si se encuentra un UNO
        }
    }

    return hayUno ? UNO : CERO; // Si hay un número impar de UNO, la salida es UNO, de lo contrario es CERO
}

std::string XorM::tipo() {
    return "XORM";
}

std::string XorM::toString(int numEsp) {
    std::string resultado;
    for (Puerta* p : this->Entradas) {
        if (p != nullptr) resultado += p->toString(numEsp); // Concatenar la representación de cada entrada con el número de espacios adecuado
    }
    return resultado;
}

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.