Solution
/*
Programmer: Jennifer Leopold
Date: February 28, 2018
File: hw6.cpp
Purpose: Simulate a vending machine that sells snacks and
computes pounds user will lose by eating the
selected item based on user's metabolic rate.
To compile: fg++ hw6.cpp -o hw6
To execute: ./hw6
*/
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// Menu selections
const string MENU_ITEM_1 = "Dry Hay";
const string MENU_ITEM_2 = "Wet Hay";
const string MENU_ITEM_3 = "Kale";
const string MENU_ITEM_4 = "Ground Corn";
const string MENU_ITEM_5 = "Carrots";
const string MENU_ITEM_6 = "Carrots";
const string MENU_ITEM_7 = "Carrots";
const string MENU_ITEM_8 = "Industrially Milled Fortified "
"Sawdust Horse Feed";
const string MENU_ITEM_QUIT = "Quit";
const int NUM_MENU_ITEMS = 9;
// User limited to # selections from vending machine
const int MAX_SELECTIONS = 10;
// Price for each menu item
const float MENU_ITEM_1_PRICE = 1.5;
const float MENU_ITEM_2_PRICE = 1.25;
const float MENU_ITEM_3_PRICE = 0.75;
const float MENU_ITEM_4_PRICE = 2.5;
const float MENU_ITEM_5_PRICE = 1;
const float MENU_ITEM_6_PRICE = 1;
const float MENU_ITEM_7_PRICE = 1;
const float MENU_ITEM_8_PRICE = 0.5;
// Metabolic weight loss multiplying factor for each item
const int MENU_ITEM_1_WEIGHT_LOSS_FACTOR = 34;
const int MENU_ITEM_2_WEIGHT_LOSS_FACTOR = 33;
const int MENU_ITEM_3_WEIGHT_LOSS_FACTOR = 26;
const int MENU_ITEM_4_WEIGHT_LOSS_FACTOR = 12;
const int MENU_ITEM_5_WEIGHT_LOSS_FACTOR = 25;
const int MENU_ITEM_6_WEIGHT_LOSS_FACTOR = 25;
const int MENU_ITEM_7_WEIGHT_LOSS_FACTOR = 25;
const int MENU_ITEM_8_WEIGHT_LOSS_FACTOR = 13;
// Valid range for user's metabolic rate
const float METABOLIC_RATE_LOW = 0.05;
const float METABOLIC_RATE_HIGH = 0.09;
// Probabality of vending machine malfunctioning,
// # of multiple items dispensed, # "crap" items
const int PROB_DIFFERENT_SELECTION = 20;
const int PROB_NO_CHANGE_GIVEN = 45;
const int PROB_MULTIPLES_DISPENSED = 10;
const int PROB_CRAP_DISPENSED = 15;
const int PROB_NOTHING_DISPENSED = 25;
const int PROB_NORMAL_ITEM_DISPENSED = 50;
const int PROB_CRAP_DISPENSED_INCREMENT = 5;
const int NUM_MULTIPLES_DISPENSED = 7;
const int NUM_CRAP_ITEMS = 3;
// ***** Function Prototypes *****
void greetUser();
float getMetabolicRate();
void displayMenu();
int getMenuSelection();
float getMenuItemAmtOwed(const int menuChoice);
string getMenuItemName(const int menuChoice);
float calculateWeightLoss(const int menuChoice,
const float metabolicRate);
bool isTimeToQuit(const int menuChoice);
void processPayment(const float amtOwed);
void outputWeightLossMessage(const int menuChoice,
const float metabolicRate);
void outputCrapItemMessage();
void dispenseItem(const int menuChoice,
const float metabolicRate);
void randomlyOverrideMenuSelection(int &menuChoice);
int randomProbability();
void signOff();
// ***** Function Definitions *****
void greetUser()
{
cout << "\nWelcome to the Healthy Living "
<< "Vending Machine!\n\n";
return;
}
float getMetabolicRate()
{
float metabolicRate;
bool validInput;
do
{
cout << "Enter your metabolic rate ("
<< METABOLIC_RATE_LOW << "-"
<< METABOLIC_RATE_HIGH << "): ";
cin >> metabolicRate;
validInput = (metabolicRate >= METABOLIC_RATE_LOW) &&
(metabolicRate <= METABOLIC_RATE_HIGH);
if (! validInput)
cout << "Invalid input!\n";
} while (! validInput);
return(metabolicRate);
}
void displayMenu()
{
cout << "\nHere's what we have for you today:\n";
cout << " 1. " << MENU_ITEM_1 << "\t\t$"
<< MENU_ITEM_1_PRICE << "\t("
<< MENU_ITEM_1_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 2. " << MENU_ITEM_2 << "\t\t$"
<< MENU_ITEM_2_PRICE << "\t("
<< MENU_ITEM_2_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 3. " << MENU_ITEM_3 << "\t\t$"
<< MENU_ITEM_3_PRICE << "\t("
<< MENU_ITEM_3_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 4. " << MENU_ITEM_4 << "\t$"
<< MENU_ITEM_4_PRICE << "\t("
<< MENU_ITEM_4_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 5. " << MENU_ITEM_5 << "\t\t$"
<< MENU_ITEM_5_PRICE << "\t("
<< MENU_ITEM_5_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 6. " << MENU_ITEM_6 << "\t\t$"
<< MENU_ITEM_6_PRICE << "\t("
<< MENU_ITEM_6_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 7. " << MENU_ITEM_7 << "\t\t$"
<< MENU_ITEM_7_PRICE << "\t("
<< MENU_ITEM_7_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 8. " << MENU_ITEM_8 << " $"
<< MENU_ITEM_8_PRICE << "\t("
<< MENU_ITEM_8_WEIGHT_LOSS_FACTOR << ")" << endl;
cout << " 9. " << MENU_ITEM_QUIT << endl;
return;
}
int getMenuSelection()
{
int menuChoice;
bool validInput;
do
{
cout << "Please make a selection (1-"
<< NUM_MENU_ITEMS << "): ";
cin >> menuChoice;
validInput = (menuChoice >= 1) &&
(menuChoice <= NUM_MENU_ITEMS);
if (! validInput)
cout << "Invalid selection!\n";
} while (! validInput);
return(menuChoice);
}
float getMenuItemAmtOwed(const int menuChoice)
{
float amtOwed;
switch (menuChoice)
{
case 1: amtOwed = MENU_ITEM_1_PRICE;
break;
case 2: amtOwed = MENU_ITEM_2_PRICE;
break;
case 3: amtOwed = MENU_ITEM_3_PRICE;
break;
case 4: amtOwed = MENU_ITEM_4_PRICE;
break;
case 5: // Items 5-7 are all the same
case 6:
case 7: amtOwed = MENU_ITEM_7_PRICE;
break;
case 8: amtOwed = MENU_ITEM_8_PRICE;
break;
case 9: amtOwed = 0;
}
return(amtOwed);
}
string getMenuItemName(const int menuChoice)
{
string selectedItemName;
switch (menuChoice)
{
case 1: selectedItemName = MENU_ITEM_1;
break;
case 2: selectedItemName = MENU_ITEM_2;
break;
case 3: selectedItemName = MENU_ITEM_3;
break;
case 4: selectedItemName = MENU_ITEM_4;
break;
case 5: // Items 5-7 are all the same
case 6:
case 7: selectedItemName = MENU_ITEM_7;
break;
case 8: selectedItemName = MENU_ITEM_8;
break;
case 9: selectedItemName = "";
}
return(selectedItemName);
}
float calculateWeightLoss(const int menuChoice,
const float metabolicRate)
{
float weightLoss;
switch (menuChoice)
{
case 1: weightLoss = MENU_ITEM_1_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 2: weightLoss = MENU_ITEM_2_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 3: weightLoss = MENU_ITEM_3_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 4: weightLoss = MENU_ITEM_4_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 5: // Items 5-7 are all the same
case 6:
case 7: weightLoss = MENU_ITEM_7_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 8: weightLoss = MENU_ITEM_8_WEIGHT_LOSS_FACTOR *
metabolicRate;
break;
case 9: weightLoss = 0;
}
return(weightLoss);
}
bool isTimeToQuit(const int menuChoice)
{
return(menuChoice == NUM_MENU_ITEMS);
}
void processPayment(const float amtOwed)
{
float amountRendered; // amt paid by user
bool validInput; // whether user's input is valid
float changeDue; // amt due to user
// Ask user to deposit amount due
do
{
cout << "\nPlease deposit $" << amtOwed << ": ";
cin >> amountRendered;
validInput = amountRendered >= amtOwed;
if (! validInput)
cout << "Umm, that isn't enough!\n";
} while (!validInput);
// Give back change (if any due)
changeDue = amountRendered - amtOwed;
if (changeDue > 0)
{
// Sometimes machine won't give any change due
if (randomProbability() <= PROB_NO_CHANGE_GIVEN)
cout << "Sorry, no change for you!\n";
else cout << "Your change is $" << changeDue << endl;
}
return;
}
void outputWeightLossMessage(const int menuChoice,
const float metabolicRate)
{
cout << "BTW, by eating one package of "
<< getMenuItemName(menuChoice)
<< ", you will lose "
<< calculateWeightLoss(menuChoice, metabolicRate)
<< " lbs!\n";
return;
}
void outputCrapItemMessage()
{
// Randomly pick a "crap" item to "dispense"
switch (rand() % NUM_CRAP_ITEMS)
{
case 0: cout << "Eeew! Here's a dead mousie for you"
<< "..been in there for a while!\n";
break;
case 1: cout << "Here's a circuit board...I have a small "
<< "internal fire here!\nRun! What are you "
<< "standing there for??\n";
break;
case 2: cout << "Here's a Dylan5 doll...ZZZZZZZZ\n";
}
return;
}
void dispenseItem(const int menuChoice,
const float metabolicRate)
{
int chance; // prob of what user actually gets
bool gotItem; // whether user got an item
static int chanceNormal = PROB_NORMAL_ITEM_DISPENSED;
static int chanceCrap = PROB_CRAP_DISPENSED;
static int chanceNothing = PROB_NOTHING_DISPENSED;
// Determine how machine will malfunction in terms of
// what it will actually dispense
chance = randomProbability();
if (chance < chanceNormal)
gotItem = true;
else if (chance < (chanceNormal + chanceCrap))
{
gotItem = false;
outputCrapItemMessage();
}
else if (chance < (chanceNormal + chanceCrap + chanceNothing))
{
gotItem = false;
cout << "Nothing for you, sucker! I don't care if "
<< "you paid!\n";
}
else {
gotItem = true;
cout << "Woohoo, you get " << NUM_MULTIPLES_DISPENSED
<< " packages of these!\n";
}
// If user actually got a legitimate item, output weight
// loss info
if (gotItem)
outputWeightLossMessage(menuChoice,metabolicRate);
// Everytime this function is called, the probability
// user will get crap increases and probability user
// will get normal item decreases
chanceCrap += PROB_CRAP_DISPENSED_INCREMENT;
chanceNormal -= PROB_CRAP_DISPENSED_INCREMENT;
return;
}
void randomlyOverrideMenuSelection(int &menuChoice)
{
if (randomProbability() <= PROB_DIFFERENT_SELECTION)
menuChoice = (rand() % NUM_MENU_ITEMS) + 1;
return;
}
int randomProbability()
{
return(rand() % 101); // 0..100
}
void signOff()
{
cout << "\nStay healthy my friend!\n";
return;
}
int main()
{
float metabolicRate; // user's metabolic rate
int menuChoice; // user's vending machine choice
string selectedItemName; // chosen vending item name
float amtOwed; // amt owed for vending item
float weightLoss; // # lbs lost for item eaten
int numSelections = 0; // # selections made
// Seed random # generator
//srand(555);
srand(time(NULL));
// Greet user
greetUser();
// Get input for user's metabolic rate
metabolicRate = getMetabolicRate();
// Set precision to 2 decimal places for numeric outputs
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
// Let user repeatedly make selections from the vending
// machine until s/he chooses to 'quit'
do
{
// Display choices and get menu selection
displayMenu();
menuChoice = getMenuSelection();
// Sometimes machine will give you something else
randomlyOverrideMenuSelection(menuChoice);
numSelections++;
if (!isTimeToQuit(menuChoice))
{
cout << "You chose " << getMenuItemName(menuChoice)
<< endl;
// Process user's payment and dispense item
processPayment(getMenuItemAmtOwed(menuChoice));
dispenseItem(menuChoice, metabolicRate);
// Machine kicks user out after certain # of selections
if (numSelections > MAX_SELECTIONS)
cout << "Get lost, Pal! "
<< "You've gotten enough of me already!\n";
}
} while (!isTimeToQuit(menuChoice) &&
(numSelections <= MAX_SELECTIONS));
// Sign off
signOff();
return 0;
}