Wednesday, June 14, 2017

Programming Challenge 11.13 - Drink Machine Simulator

Include File: UtilityCls.h


/* Drink Machine Simulator - This program simulates a soft drink machine.
    The program uses a structure that stores the following data:
   
        * Drink Name
        * Drink Cost
        * Number of Drinks in Machine

    The program creates an array of five structures. The elements are
    initialized with the following data:

        * Drink Name                    Cost                    Number in Machine
          ----------------                    -----                     ------------------------
          Cola                                    .75                                                20
          Root Beer                            .75                                               20
          Lemon-Lime                       .75                                               20
          Grape Soda                         .80                                                20
          Cream Soda                        .80                                                20
   
    Each time the program runs, it enters a loop that performs the following
    steps: A list of drinks is displayed on the screen. The user is allowed
    to either quit the program or pick a drink. If the user selects a drink,
    he or she will next enter the amount of money that is to be inserted into
    the drink machine. The program displays the amount of change that would be
    returned and subtract one from the number of that drink left in the machine.
    If the user selects a drink that has sold out, a message is displayed. The
    loop then repeats. When the user chooses to quit the program it displays the
    total amount of money the machine earned.

    Input Validation: When the user enters an amount of money, no negative values
    or values greater than $1.00 are accepted. */

#include "UtilityCls.h"

struct Hanbaiki
{
    string drinkName;        /*    Name of the drinks */
    double cost;             /* Product price         */
    int    numDrinks;        /* Number of drinks   */

    Hanbaiki(string d = "N/A", double c = 0.0, int n = 20)
    {
        drinkName = d;
        cost = c;
        numDrinks = n;
    }

    ~Hanbaiki()
    {
    }
};

struct Sales
{
    double revenue;            /* Gets the revenue                                            */
    double change;                /* Holds the change                                            */                                   
    double numAvailable;        /* Keeps track of the available drinks                    */
    double sumInserted;        /* Gets the amount inserted into the coin receiver */

    Sales(double rv = 0.0, double sm = 0.0, double chg = 0.0, int av = 0)
    {
        revenue = rv;
        change = chg;
        sumInserted = sm;
        numAvailable = av;
    }

    ~Sales()
    {
    }
};

enum hanbaikiMenu
{
    BUY = 1, CANCEL = 2, QUIT = 3
};

enum drinks
{
    COLA = 0, ROOT_BEER = 1, LEMON_LIME = 2, GRAPE_SODA = 3, CREAM_SODA = 4
};

enum acceptedCoins
{
    FIVE_CT = 1, TEN_CT = 2, TWENTYFIFE_CT = 3, FIFTY_CT = 4, ONE_DOLLAR = 5
};

void menu(Hanbaiki *, Sales, const int);
int  getOption();
void displayDrinks(Hanbaiki *, const int);
void calcRevenue(Hanbaiki *, Sales &, const int, const int);
int  getCoins();
void coinReceiver(Hanbaiki *, Sales, const int, const int);
bool reqRefill(Hanbaiki *, Sales, const int);

int main()
{
    const int PRODUCTS = 5;

    Sales rev;

    Hanbaiki drinks[PRODUCTS] = { { "COLA",         0.75 },
                                            { "ROOT BEER",  0.75 },
                                            { "LEMON LIME", 0.75 },
                                            { "GRAPE SODA", 0.80 },
                                            { "CREAM SODA", 0.80 } };

    menu(drinks, rev, PRODUCTS);

   return 0;
}

/* **********************************************************
   Definition: menu

    This function accepts an array of structs and a structure
    as argument. It acts as the main menu from which all other
    functions are called.
   ********************************************************** */

void menu(Hanbaiki *drinks, Sales rev, const int PRODUCTS)
{
    int  selection = 0;
    int  option = 0;
    bool isEmpty = false;

    do
    {
        cout << fixed << showpoint << setprecision(2);
        cout << "\n\tSUNTORY Soft Drinks\n\n";

        displayDrinks(drinks, PRODUCTS);
       
        cout << "\n\n\tSelect [0 = Cancel | Options]: ";
        cin >> selection;

        if (selection == 0)
        {
            option = getOption();
        }
        else
        {
            selection -= 1;

            while (selection < COLA || selection > CREAM_SODA)
            {
                cout << "\n\tSelect [0 = Cancel | Options]: ";
                cin >> selection;

                selection -= 1;
            }

            option = getOption();
        }

        switch (option)
        {
            case BUY:
            {               
                if (drinks[selection].numDrinks != 0 && option != CANCEL)
                {
                    coinReceiver(drinks, rev, selection, PRODUCTS);
                    pauseSystem();
                    clearScreen();
                    calcRevenue(drinks, rev, selection, PRODUCTS);
                }
                else
                {
                    clearScreen();
                }

                if (isEmpty = reqRefill(drinks, rev, PRODUCTS))
                {
                    cout << fixed << showpoint << setprecision(2);
                   cout << "\n\n\tVENDING MACHINE EMPTY\n\n"
                          << "\tPlease call SUNTORY: 0421-5884929\n\n"
                         << "\tSUNTORY - Your number one in Soft Drinks\n\n"
                         << "\tTotal Revenue: " << rev.revenue << " $\n";

                    option = 3;
                    pauseSystem();
                }
            } break;

            case CANCEL:
            {
                clearScreen();
            } break;

            case QUIT:       
            {
                cout << "\n\n\tSUNTORY - Your number one in Soft Drinks\n\n";
                cout << "\tTotal Revenue: " << rev.revenue << " $\n";

                pauseSystem();
            } break;
        }
    } while (option != QUIT);
}

/* **********************************************************
   Definition: getOption

    This function asks the buyer to select from the following
    options:

        * BUY            To buy a drink
        * CANCEL        To cancel the transaction
        * QUIT        To exit the program

    The selection is returned from the function.
   ********************************************************** */

int getOption()
{
    int option = 0;

    cout << "\n\t1: BUY"
          << "\n\t2: CANCEL"
          << "\n\t3: QUIT\n\n"
          << "\tOption: ";
    cin >> option;

    while (option < BUY || option > QUIT)
    {
        cout << "\n\tOption: ";
        cin >> option;
    }

    return option;
}

/* **********************************************************
   Definition: displayDrinks

    This function accepts an array of structs as argument. It
    displays a list of drinks, their names, price and the
    number of available products. If the number of drinks is
    0, 'OUT OF STOCK' is output.
   ********************************************************** */

void displayDrinks(Hanbaiki *drinks, const int PRODUCTS)
{   
        cout << "\t[  1  ] "          << drinks[COLA].drinkName
              << setw(23) << right << drinks[COLA].cost;
   
        drinks[COLA].numDrinks > 0 ? cout << setw(23) << right
                                                     << "Drinks Left: " << drinks[COLA].numDrinks :
                                              cout << setw(24) << right << "OUT OF STOCK";
   
        cout << "\n\t[  2  ] "      << drinks[ROOT_BEER].drinkName
              << setw(18) << right << drinks[ROOT_BEER].cost;
   
        drinks[ROOT_BEER].numDrinks > 0 ? cout << setw(23) << right << "Drinks Left: "
                                                           << drinks[ROOT_BEER].numDrinks :
                                                     cout << setw(24) << right << "OUT OF STOCK";

        cout << "\n\t[  3  ] "      << drinks[LEMON_LIME].drinkName
              << setw(17) << right << drinks[LEMON_LIME].cost;         

        drinks[LEMON_LIME].numDrinks > 0 ? cout << setw(23) << right << "Drinks Left: "
                                                             << drinks[LEMON_LIME].numDrinks :
                                                      cout << setw(24) << right << "OUT OF STOCK";

        cout << "\n\t[  4  ] "      << drinks[GRAPE_SODA].drinkName
              << setw(17) << right << drinks[GRAPE_SODA].cost;

        drinks[GRAPE_SODA].numDrinks > 0 ? cout << setw(23) << right << "Drinks Left: "
                                                             << drinks[GRAPE_SODA].numDrinks :
                                                      cout << setw(24) << right << "OUT OF STOCK";

        cout << "\n\t[  5  ] "      << drinks[CREAM_SODA].drinkName
              << setw(17) << right << drinks[CREAM_SODA].cost;

        drinks[CREAM_SODA].numDrinks > 0 ? cout << setw(23) << right << "Drinks Left: "
                                                             << drinks[CREAM_SODA].numDrinks :
                                                      cout << setw(26) << right << "OUT OF STOCK\n\n";
}

/* **********************************************************
    Definition: coinReceiver

    This function accepts an array of structs and a structure
    as arguments. It acts as coin receiver. It keeps track of
    the amount of money inserted, which is constantly updated
    and displayed. If the amount of money received is greater
    than the product cost, the change is calculated, and the
    amount a buyer would normally receive is displayed.
    ********************************************************** */

void coinReceiver(Hanbaiki *drinks, Sales rev, const int selection,
                       const int PRODUCTS)
{
    const double coins[5] = { .05, .10, .25, .50, 1.0 };

    int insert = 0;

    do
    {
        insert = getCoins();

        if (rev.sumInserted < drinks[selection].cost)
        {
            cout << "\n\tYou inserted: " << (rev.sumInserted += coins[insert - 1]) << "\n";

            if (rev.sumInserted > drinks[selection].cost)
            {
                rev.change = rev.sumInserted - drinks[selection].cost;
                rev.sumInserted = drinks[selection].cost;

                cout << "\n\tChange: " << rev.change << " ct.\n";
            }           
        }
    } while (drinks[selection].cost != rev.sumInserted);
}

/* **********************************************************
   Definition: getCoins

    This function displays a list of coins the buyer is asked
    to insert. The lowest amount being five cents, the highest
    one dollar. The selection is returned.
   ********************************************************** */

int getCoins()
{
    int insert = 0;

    cout << "\n\t[ 1. ]" << setw(12) << right <<  "5 ct.\n"
          << "\t[ 2. ]"   << setw(12) << right << "10 ct.\n"
          << "\t[ 3. ]"   << setw(12) << right << "25 ct.\n"
          << "\t[ 4. ]"   << setw(12) << right << "50 ct.\n"
          << "\t[ 5. ]"   << setw(13) << right << " 1  D.\n\n";
    cout << "\tInsert: ";
    cin >> insert;

    while (insert < FIVE_CT || insert > ONE_DOLLAR)
    {
        cout << "\tInsert: ";
        cin >> insert;
    }

    return insert;
}

/* **********************************************************
    Definition: calcRevenue

    This function accepts an array of structs, a structure
    as argument. It calculates the revenue and stores it in
    the appropriate member of the Sales structure. It also
    deducts 1 from the number of available drinks after a
    sale has taken place.
    ********************************************************** */

void calcRevenue(Hanbaiki *drinks, Sales &rev, const int selection,
                      const int PRODUCTS)
{
    rev.revenue += drinks[selection].cost;

    drinks[selection].numDrinks -= 1;
}

/* **********************************************************
   Definition: reqRefill

    This function accepts an array of structs and a structure
    as arguments. It keeps track of the total number of drinks
    which is stored in the appropriate member of the Sales
    structure. This information is returned from the function.
   ********************************************************** */

bool reqRefill(Hanbaiki *drinks, Sales rev, const int PRODUCTS)
{
    bool isEmpty = false;

    for (int index = 0; index < PRODUCTS; index++)
    {
        rev.numAvailable += drinks[index].numDrinks;
    }

    if (rev.numAvailable == 0)
    {
        isEmpty = true;
    }

    return isEmpty;
}

Example Output:





No comments:

Post a Comment