From fe5269b6edf4960d4191cb8f169cdc4a8b380cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abdulkadir=20Furkan=20=C5=9Eanl=C4=B1?= Date: Tue, 4 Jan 2022 18:05:39 +0100 Subject: [PATCH] More stuff. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Abdulkadir Furkan Şanlı --- bank.cpp | 184 +++++++++++++++++++++++++++++++++++++++++++++++++------ bank.h | 26 ++++---- 2 files changed, 181 insertions(+), 29 deletions(-) diff --git a/bank.cpp b/bank.cpp index b8640cd..ba6b72d 100644 --- a/bank.cpp +++ b/bank.cpp @@ -1,6 +1,7 @@ #include "bank.h" +#include #include - +#include // rand(), srand() using namespace std; double @@ -30,26 +31,46 @@ Bank::countEmployees () cout << employees.size () << " employees." << endl; } -// Open account if enough employee capacity. bool Bank::openAccount (Client &x) { - if (employees.size () == 0) - return false; if (employees.size () * CLIENT_EMPLOYEE <= clients.size ()) - return false; + return false; // Insufficient employee capacity. for (auto i : x.accounts) if (i == this) return false; - clientRecord newClient; newClient.id = x.id; clients.push_back (newClient); x.accounts.push_back (this); - return true; } +bool +Bank::closeAccount (Client &x) +{ + for (auto i = clients.begin (); i != clients.end (); i++) + if (i->id == x.id) + { + if (i->loans.size () != 0) + return false; // Can't close account with outstanding loans. + else if (this->withdraw (x, this->getCurrent (x)) == -2) + return false; // Bank can't pay for withdrawal. + else + { + clients.erase (i); + for (auto j = x.accounts.begin (); j != x.accounts.end (); j++) + if (*j == this) + { + auto position = j - x.accounts.begin (); + x.accounts.erase (x.accounts.begin () + position); + return true; + } + } + } + return false; // Account doesn't exist. +} + bool Bank::hire (Employee &x) { @@ -63,8 +84,6 @@ Bank::hire (Employee &x) bool Bank::fire (Employee &x) { - if (x.employer != this) - return false; for (auto i = employees.begin (); i != employees.end (); i++) if (*i == &x) { @@ -72,8 +91,7 @@ Bank::fire (Employee &x) x.employer = nullptr; return true; } - cout << "Bank doesn't have employee listed, but employee does." << endl; - exit (EXIT_FAILURE); + return false; // Can't fire unemployed. } // Deposit money from under the mattress, return amount. @@ -82,9 +100,11 @@ Bank::deposit (Client &x, const double amount) { if (amount == 0) return 0; + if (amount < 0) + return 0; // Can't be negative. if (x.underMattress < amount) return 0; - for (auto i = clients.begin(); i != clients.end(); i++) + for (auto i = clients.begin (); i != clients.end (); i++) if (i->id == x.id) { x.underMattress -= amount; @@ -92,8 +112,53 @@ Bank::deposit (Client &x, const double amount) current += amount; return amount; } - cout << "Client doesn't have an account at bank." << endl; - return 0; + return -1; // No such account. +} + +// Withdraw from current account, if bank doesn't have amount in current, will +// attempt to withdraw required amount from Gov. If unable, will attempt +// bailout. +double +Bank::withdraw (Client &x, const double amount) +{ + if (amount == 0) + return 0; + if (amount < 0) + return 0; // Can't be negative. + if (current < amount) // TODO: bailout mechanism. + if (this->centralBank->reserveWithdraw (*this, ceil (amount - current)) + < 0) + if (!this->centralBank->bailout (*this, ceil (amount - current))) + return -3; // Bank unable to pay, wasn't bailed out. + for (auto i = clients.begin (); i != clients.end (); i++) + if (i->current < amount) + return 0; + else + { + i->current -= amount; + x.underMattress += amount; + current -= amount; + return amount; + } + return -1; // No such account. +} + +double +Bank::getCurrent () +{ + return current; +} + +double +Bank::getCreditable () +{ + return creditable; +} + +double +Bank::getCredited () +{ + return credited; } double @@ -106,10 +171,67 @@ Bank::getCurrent (const Client &x) return 0; } -void +bool Gov::associate (Bank *const x) { + for (auto i = banks.begin (); i != banks.end (); i++) + if (*i == x) + return false; // Can't associate twice. + x->centralBank = this; banks.push_back (x); + return true; +} + +double +Gov::getReserve () +{ + return reserve; +} + +double +Gov::reserveDeposit (Bank &x, const double amount) +{ + if (amount == 0) + return 0; + if (amount < 0) + return 0; // Can't be negative. + if (x.current < amount) + return 0; + x.current -= amount; + reserve += amount; + x.creditable += amount * FACTOR; + return amount; +} + +double +Gov::reserveWithdraw (Bank &x, const double amount) +{ + if (amount == 0) + return 0; + if (amount < 0) + return 0; // Can't be negative. + if (x.creditable < amount * FACTOR) + return -3; // Bank can't repay. + x.creditable -= amount * FACTOR; + reserve -= amount; + x.current += amount; + return amount; +} + +// Gov bailout for Bank's unfulfillable Client withdrawals. 50% chance, seeded +// with time since last bailout. +bool +Gov::bailout (Bank &x, const double amount) +{ + auto now = time (0); + srand (now - lastBailout); + if (rand () > (RAND_MAX / 2)) + { + lastBailout = now; + x.current += amount; // Just like magic. + return true; + } + return false; } int @@ -123,26 +245,52 @@ main () Gov fed; Bank boa (&fed); + cout << fed.associate (&boa) << endl; // Can't associate twice. - boa.countEmployees (); + cout << boa.openAccount (abdul) << endl; + boa.countEmployees (); // Insufficient employee capacity. boa.hire (dude); boa.countEmployees (); - boa.fire (gal); + boa.fire (gal); // Can't fire non-employed. boa.countEmployees (); boa.fire (dude); boa.countEmployees (); boa.hire (gal); boa.hire (dude); + boa.hire (dude); // Can't hire employed. boa.countEmployees (); - boa.openAccount (abdul); + cout << boa.openAccount (abdul) << endl; + cout << boa.openAccount (abdul) + << endl; // Can't open existing client account. boa.listClients (); cout << abdul.getMattress () << " under mattress." << endl; boa.deposit (abdul, 500); cout << boa.getCurrent (abdul) << " in bank account." << endl; cout << abdul.getMattress () << " under mattress." << endl; + cout << boa.getCurrent () << " in bank current accounts." << endl; + boa.withdraw (abdul, 30); + Client jane ("jane"); + jane.earn (1000); + cout << jane.getMattress () << " under mattress." << endl; + boa.openAccount (jane); + boa.deposit (jane, 500); + cout << boa.getCurrent (abdul) << " in bank account." << endl; + cout << abdul.getMattress () << " under mattress." << endl; + cout << boa.getCurrent (jane) << " in bank account." << endl; + cout << jane.getMattress () << " under mattress." << endl; + cout << boa.getCurrent () << " in bank current accounts." << endl; + + Client joe ("joe"), bob ("bob"), frank ("frank"); + boa.openAccount (joe); + boa.openAccount (joe); // Second open call. + boa.openAccount (bob); + boa.openAccount (frank); // Insufficient employee capacity. Sorry frank. + boa.listClients (); + boa.closeAccount (abdul); + boa.listClients (); return 0; } diff --git a/bank.h b/bank.h index e50c413..6ddb55c 100644 --- a/bank.h +++ b/bank.h @@ -12,17 +12,17 @@ class Gov; class Gov { public: - int factor = 6; // Money multiplier. - int rate = 2; // Interest rate (%). - time_t last_bailout = 0; // Time since last bailout. - void associate (Bank *const x); - bool disassociate (Bank *const x); - double reserveDeposit (const Bank &x, const double amount); - double reserveWithdraw (const Bank &x, const double amount); - bool bailout (const Bank &x, double amount); + static const int FACTOR = 6; // Money multiplier. + int rate = 2; // Interest rate (%). + bool associate (Bank *const x); + double reserveDeposit (Bank &x, const double amount); + double reserveWithdraw (Bank &x, const double amount); + bool bailout (Bank &x, const double amount); + double getReserve (); private: - double bankReserves = 0; + time_t lastBailout = 0; // Time since last bailout. + double reserve = 0; // Total in bank reserves. std::vector banks; }; @@ -31,14 +31,17 @@ class Bank friend class Gov; public: - Gov *centralBank; - Bank (Gov *x) : centralBank (x) { x->associate (this); }; + Bank (Gov *x) : centralBank (x) { x->associate (this); }; // Must have Gov. double deposit (Client &x, const double amount); double withdraw (Client &x, const double amount); + double getCurrent (); double getCurrent (const Client &x); + double getCreditable (); + double getCredited (); bool hire (Employee &x); bool fire (Employee &x); bool openAccount (Client &x); + bool closeAccount (Client &x); bool newCredit (const std::string id, const double amount, const int installments, const int days, const float interest); // interest is additional interest on @@ -48,6 +51,7 @@ public: void listClients (); private: + Gov *centralBank; const int CLIENT_EMPLOYEE = 2; // Max number of clients to employees. double current = 0; // Total current accts. of clients. double creditable = 0; // Amount able to be loaned to clients.