More stuff.

Signed-off-by: Abdulkadir Furkan Şanlı <me@abdulocra.cy>
This commit is contained in:
Abdulkadir Furkan Şanlı
2022-01-04 18:05:39 +01:00
parent 28ae19695b
commit fe5269b6ed
2 changed files with 181 additions and 29 deletions
+166 -18
View File
@@ -1,6 +1,7 @@
#include "bank.h"
#include <cmath>
#include <iostream>
#include <stdlib.h> // 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;
}
+15 -11
View File
@@ -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<Bank *> 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.