# Object Oriented Programming - IT002.O21.CNVN
### Final Lab Test - 2024
###### jns
#
## Đề :


## Thiết kế các class cần thiết:

## Source code:
### headers:
#### gate.h
```cpp
#ifndef GATE_H_INCLUDED
#define GATE_H_INCLUDED
#include <iostream>
#include <vector>
#include "phineas.h"
using namespace std;
enum type{
BUSINESS_GATE,
ACADEMIC_GATE,
POWER_GATE
};
class default_gate {
private:
type gate_type;
public:
default_gate(type gate_type);
type getGateType();
virtual bool canPass(phineas * Phineas) = 0;
};
class business_gate : public default_gate {
private:
int cash;
int nums_product;
public:
business_gate(int cash, int nums_product);
bool canPass(phineas * Phineas) override;
void afterPass(phineas * Phineas);
};
class academic_gate : public default_gate {
private:
int req_iq;
public:
academic_gate(int req_iq);
bool canPass(phineas * Phineas) override;
};
class power_gate : public default_gate {
private:
int req_mana;
public:
power_gate(int req_mana);
bool canPass(phineas * Phineas) override;
void afterPass(phineas * Phineas);
};
#endif // GATE_H_INCLUDED
```
#### phineas.h
```cpp
#ifndef PHINEAS_H_INCLUDED
#define PHINEAS_H_INCLUDED
#include <iostream>
using namespace std;
class phineas {
private:
int cash;
int iq;
int mana;
public:
phineas(int cash, int iq, int mana);
//setter
void setCash(int cash);
void setIq(int iq);
void setMana(int mana);
//getter
int getCash();
int getIq();
int getMana();
void outP();
};
#endif // PHINEAS_H_INCLUDED
```
#### tower.h
```cpp
#ifndef TOWER_H_INCLUDED
#define TOWER_H_INCLUDED
#include "gate.h"
class tower {
private:
int N;
public:
vector <default_gate *> gates;
tower();
void insert(default_gate * gate) {
gates.push_back(gate);
}
void input();
void output() {
for (int i = 0; i < N; i++) {
cout << "Gate " << i + 1 << ": ";
if (gates[i]->getGateType() == BUSINESS_GATE) {
cout << "Business Gate" << endl;
} else if (gates[i]->getGateType() == ACADEMIC_GATE) {
cout << "Academic Gate" << endl;
} else if (gates[i]->getGateType() == POWER_GATE) {
cout << "Power Gate" << endl;
}
}
}
~tower(){
for (int i = 0; i < N; i++) {
delete gates[i];
}
};//destructor
};
#endif // TOWER_H_INCLUDED
```
### source:
#### gate.cpp
```cpp
#include "../headers/gate.h"
default_gate::default_gate(type gate_type) {
this->gate_type = gate_type;
}
type default_gate::getGateType() {
return this->gate_type;
}
business_gate::business_gate(int cash, int nums_product) : default_gate(BUSINESS_GATE) {
this->cash = cash;
this->nums_product = nums_product;
}
void business_gate::afterPass(phineas * Phineas) {
Phineas->setCash(Phineas->getCash() - this->cash * this->nums_product);
}
bool business_gate::canPass(phineas * Phineas) {
int phineas_cash = Phineas->getCash();
return (phineas_cash >= this->cash * this->nums_product);
}
academic_gate::academic_gate(int req_iq) : default_gate(ACADEMIC_GATE) {
this->req_iq = req_iq;
}
bool academic_gate::canPass(phineas * Phineas) {
int phineas_iq = Phineas -> getIq();
return phineas_iq >= this->req_iq;
}
power_gate::power_gate(int req_mana) : default_gate(POWER_GATE) {
this->req_mana = req_mana;
}
bool power_gate::canPass(phineas * Phineas) {
int phineas_mana = Phineas -> getMana();
return phineas_mana >= this->req_mana;
}
void power_gate::afterPass(phineas * Phineas) {
Phineas->setMana(Phineas->getMana() - this->req_mana);
}
```
#### phineas.cpp
```cpp
#include "../headers/phineas.h"
phineas::phineas(int cash, int iq, int mana) {
this->cash = cash;
this->iq = iq;
this->mana = mana;
}
int phineas::getCash() {
return cash;
}
int phineas::getIq() {
return iq;
}
int phineas::getMana() {
return mana;
}
void phineas::setCash(int cash) {
this->cash = cash;
}
void phineas::setIq(int iq) {
this->iq = iq;
}
void phineas::setMana(int mana) {
this->mana = mana;
}
void phineas::outP(){
cout << "Cash: " << this->cash << endl;
cout << "IQ: " << this->iq << endl;
cout << "Mana: " << this->mana << endl;
}
```
#### tower.cpp
```cpp
#include "../headers/tower.h"
tower::tower()
{
this->N = 0;
this->gates = vector<default_gate *>();
}
void tower::input() {
cout << "Input number of gates: ";
cin >> N;
vector <default_gate *> gates(N);
for (int i = 0; i < N; i++) {
cout << "Input gate type: (0: Business Gate, 1: Academic Gate, 2: Power Gate) ";
int gate_type;
cin >> gate_type;
while (gate_type < 0 || gate_type > 2) {
cout << "Invalid gate type. Please input again: ";
cin >> gate_type;
}
if (gate_type == BUSINESS_GATE) {
cout << "Input cash and nums_product: ";
int cash, nums_product;
cin >> cash >> nums_product;
business_gate * bg = new business_gate(cash, nums_product);
insert(bg);
} else if (gate_type == ACADEMIC_GATE) {
cout << "Input req_iq: ";
int req_iq;
cin >> req_iq;
academic_gate * ag = new academic_gate(req_iq);
insert(ag);
} else if (gate_type == POWER_GATE) {
cout << "Input req_mana: ";
int req_mana;
cin >> req_mana;
power_gate * pg = new power_gate(req_mana);
insert(pg);
}
}
}
```
#### main.cpp
```cpp
#include "../headers/tower.h"
#include "../headers/gate.h"
#include "../headers/phineas.h"
#include <fstream>
using namespace std;
int main(){
tower Tower;
Tower.input();
ofstream file;
file.open("RESULT.OUT");
int money, iq, mana;
// Tower.output();
cout << "Enter Phineas's money, IQ, and mana:";
cin >> money >> iq >> mana;
phineas * Phineas = new phineas(money, iq, mana);
bool check[4];
int current = 0;
int gate_passed = 0;
for (auto gate : Tower.gates){
type gate_type = gate->getGateType();
if (gate_passed == 3){
file << Phineas->getCash() << " " << Phineas->getIq() << " " << Phineas->getMana() << endl;
return 0;
}
if (gate_type == BUSINESS_GATE){
business_gate * bg = dynamic_cast<business_gate *>(gate);
if (bg->canPass(Phineas)){
bg->afterPass(Phineas);
if (check[gate_type] == false){
gate_passed++;
}
check[gate_type] = true;
}
else{
cout << "Phineas cannot pass the gate " << current + 1 << endl;
return 0;
}
}
else if (gate_type == ACADEMIC_GATE){
academic_gate * ag = dynamic_cast<academic_gate *>(gate);
if (ag->canPass(Phineas)){
if (check[gate_type] == false){
gate_passed++;
}
check[gate_type] = true;
}
else{
cout << "Phineas cannot pass the gate " << current + 1 << endl;
return 0;
}
}
else if (gate_type == POWER_GATE){
power_gate * pg = dynamic_cast<power_gate *>(gate);
if (pg->canPass(Phineas)){
pg->afterPass(Phineas);
if (check[gate_type] == false){
gate_passed++;
}
check[gate_type] = true;
}
else{
cout << "Phineas cannot pass the gate " << current + 1 << endl;
return 0;
}
}
}
file << Phineas->getCash() << " " << Phineas->getIq() << " " << Phineas->getMana() << endl;
return 0;
}
```