@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user