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;

}