Sunday, March 5, 2017

Programming Challenge 7.20 - Theater Seating

Example Files: seats.txt
                         seatprices.txt
                         Utility.h

/* Theater Seating - This program can be used by a small theater to sell
   tickets for performances. The theater's auditorium has 15 rows of seats,
   with 30 seats in each row. The program displays a screen that shows which
   seats are available and which are taken.
  
   For example, the following shows a chart depicting each seat in the
   theater. Seats that are taken are represented by an * symbol, and seats
   that are available are represented by a # symbol.
                   
      * Seats

             123456789012345678901234567890
      Row 1  ***###***###*########*****####
      Row 2  ####*************####*******##
      Row 3  **###**********########****###
      Row 4  **######**************##******
      Row 5  ********#####*********########
      Row 6  ##############************####
      Row 7  #######************###########
      Row 8  ************##****############
      Row 9  #########*****############****
      Row 10 #####*************############
      Row 11 #**********#################**
      Row 12 #############********########*
      Row 13 ###***********########**######
      Row 14 ##############################
      Row 15 ##############################

   When the program begins, the seat prices are loaded from the file called
   "seatprices.txt".

   Once the prices are entered, the program displays a seating chart similar
   to the one shown above. The user may enter the row and seat numbers for
   tickets being sold. Every time a ticket or group of tickets is purchased,
   the program displays the total ticket prices and updates the seating chart.

   The program keeps a total of all ticket sales. The user is given an option
   of viewing this amount.

   The program also gives the user an option to see a list of how many seats
   have been sold, how many seats are available in each row, and how many seats
   are available in the entire auditorium.

   Input Validation: When tickets are being sold, no row or seat numbers that do
   not exist are accepted. When someone requests a particular seat, the program
   makes sure that seat is available before it is sold. */

#include "Utility.h"

/* Global constants: Number of sections, Number of Rows, Number of seats */
const int SECTIONS = 3,
          ROWS_PER_SECTION = 5,
          SEATS_IN_ROW = 30;

const char FREE = '*',
           BOOKED = '#';

typedef char auditorium[SECTIONS][ROWS_PER_SECTION][SEATS_IN_ROW];
typedef double prices[SECTIONS][ROWS_PER_SECTION][SEATS_IN_ROW];

void menu();
void fillArrayAudit(auditorium);
void fillArrayPrices(prices);
void viewStatsRow(auditorium, prices);
void viewStatsAudit(auditorium, prices, double);
void seatPrices(auditorium);
void displayAudit(auditorium);
void displayPrices(prices);
double booking(auditorium, prices, int &, int &);
bool checkAv(auditorium, int, int, int);

int main()
{
   menu();
  
   pauseSystem();

   return 0;
}

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

   This function displays a basic menu with the following
   options:

      * View Auditorium Plan - Display the auditorium
      * View Seat Prices - Displays the seat prices
      * Book Seats - Allows to book free seats
      * Sales Statistics - Displays either the complete sales
                           stats, or stats for an individual
                           row in the auditorium
      * Checkout - Quit the program
   ********************************************************** */

void menu()
{
   /* Constants: Display auditorium plan, Sales statistics,
                 Book seats, Checkout */
   const int DISPLAY_PLAN = 1,
             DISPLAY_PRICES = 2,
             SALES_STATS = 3,
             BOOK_SEATS = 4,
           
             CHECKOUT = 5;

   /* Variables: Menu item, Row number, Seat number, Number of seats */
   static int menuItem = 0,
              rowNum = 0,
              seatNum = 0,
              numSeats = 0,
              stats = 0;

   double subTotal = 0.0,
          total = 0.0;

   auditorium seats = { };
   prices seatPrices = { };

   fillArrayAudit(seats);
   fillArrayPrices(seatPrices);

   do
   {
      cout << "\n\t\tALDWYCH THEATER NOW SHOWING: AN AMERICAN IN PARIS\n\n"
           << "\t\t1. View Auditorium Plan"
           << "\t\t2. View Seat Prices"
           << "\t3. Book Seats"
           << "\t4. Sales Statistics"
           << "\t5. Checkout"
           << "\tMenu Option: ";
      cin >> menuItem;

      while (menuItem < DISPLAY_PLAN || menuItem > CHECKOUT)
      {
         cin >> menuItem;
      }

      switch (menuItem)
      {
         case 1:
         {
            clearScreen();
            displayAudit(seats);       
         }
         break;

         case 2:
            clearScreen();
            displayPrices(seatPrices);
            break;

         case 3:
         {
            total = booking(seats, seatPrices, rowNum, seatNum);
         }
         break;

         case 4:
             clearScreen();

            cout << "\n\t\tEnter 1 to view full stats, 2 to view per row stats: ";
            cin >> stats;

            stats == 1 ? viewStatsAudit(seats, seatPrices, total) :
                         viewStatsRow(seats, seatPrices);
         break;

         case 5:
            cout << "\n\n\t\tNow Leaving The Aldwych Theater Booking System!\n\n";
         break;
      }
   } while (menuItem != CHECKOUT);
}

/* **********************************************************
   Definition: fillArrayAudit

   This function accepts seats[][][] as its argument. It
   opens and processes the file "seats.txt". The content
   of this file is read-in and stored in the array.
   ********************************************************** */

void fillArrayAudit(auditorium seats)
{
   int idxX = 0,
       idxY = 0,
       idxZ = 0;

   /* Create file stream object */
   ifstream seating;
   seating.open("seats.txt");

   if (seating && !seating.eof())
   {
      for (idxX = 0; idxX < SECTIONS; idxX++)
      {
         for (idxY = 0; idxY < ROWS_PER_SECTION; idxY++)
         {
            for (idxZ = 0; idxZ < SEATS_IN_ROW; idxZ++)
            {
               seating >> seats[idxX][idxY][idxZ];
            }
         }
      }
   }
   else
   {
      cout << "\n\t\tFile open error: The file 'seats.txt' could not\n"
         << "\t\tbe opened or processed. Please make sure that the filename is\n"
         << "\t\tcorrect and the file is not damaged or has been moved from the\n"
         << "\t\tprogram folder. Please exit this program from the menu now ...\n\n";
      menu();
   }

   /* Close file: "seats.txt" */
   seating.close();
}

/* **********************************************************
   Definition: fillArrayPrices

   This function accepts seatprices[][][] as its argument. It
   opens and processes the file "seatprices.txt". The content
   of this file is read-in and stored in the array.
   ********************************************************** */

void fillArrayPrices(prices seatPrices)
{
   int idxX = 0,
       idxY = 0,
       idxZ = 0;

   /* Create file stream object */
   ifstream prices;

   /* Open file: "seatprices.txt" */
   prices.open("seatprices.txt");

   if (prices && !prices.eof())
   {
      for (idxX = 0; idxX < SECTIONS; idxX++)
      {
         for (idxY = 0; idxY < ROWS_PER_SECTION; idxY++)
         {
            for (idxZ = 0; idxZ < SEATS_IN_ROW; idxZ++)
            {
               prices >> seatPrices[idxX][idxY][idxZ];
            }
         }
      }
   }
   else
   {
      cout << "\n\t\tFile open error: The file 'seatprices.txt' could not\n"
           << "\t\tbe opened or processed. Please make sure that the filename is\n"
           << "\t\tcorrect and the file is not damaged or has been moved from the\n"
           << "\t\tprogram folder. Please exit this program from the menu now ...\n\n";

      menu();
   }

   /* Close file: "prices.txt" */
   prices.close();
}

/* **********************************************************
   Definition: displayAudit

   This function accepts auditorium[][][] as its argument. It
   displays a chart of the auditorium. Additionaly the number
   of free and booked seats is displayed.
   ********************************************************** */

void displayAudit(auditorium seats)
{
   /* Variables: Index x, Index y, Index z, Count free seats,
                 Count full seats (accumulators) */
   int idxX = 0,
       idxY = 0,
       idxZ = 0,
       cntFree = 0,
       cntFull = 0;

   for (idxX = 0; idxX < SECTIONS; ++idxX)
   {   
      cout << "\n\t\tSection " << (idxX + 1) << "\n\n" << setw(17);

      for (idxZ = 0; idxZ < SEATS_IN_ROW; ++idxZ)
      {
         cout << "" << setw(4) << (idxZ + 1) ;
      }
      cout << "\n\n";

      for (idxY = 0; idxY < 5; ++idxY)
      {
         cout << "\tROW:" << setw(5) << (idxY + 1) ;

         for (idxZ = 0; idxZ < SEATS_IN_ROW; ++idxZ)
         {       
            cout << setw(4) << seats[idxX][idxY][idxZ];

            seats[idxX][idxY][idxZ] == FREE ? cntFree += 1 : cntFull += 1;       
         }
         cout << "\n";
      }       
   }

   cout << "\n\t\tAvailable Seats: " << cntFree;
   cout << "\n\t\tBooked Seats: " << cntFull << "\n";
}

/* **********************************************************
   Definition: displayPrices

   This function accepts seatPrices[][][] as its argument. It
   displays a chart with seat prices.
   ********************************************************** */

void displayPrices(prices seatPrices)
{
   /* Variables: Index x, Index y, Index z */
   int idxX = 0,
       idxY = 0,
       idxZ = 0,
       cntFree = 0,
       cntFull = 0;

   for (idxX = 0; idxX < SECTIONS; ++idxX)
   {   
      cout << "\n\t\tSection " << (idxX + 1) << "\n\n" << setw(17);

      for (idxZ = 0; idxZ < SEATS_IN_ROW; ++idxZ)
      {
         cout << "" << setw(4) << (idxZ + 1) ;
      }
      cout << "\n\n";

      for (idxY = 0; idxY < 5; ++idxY)
      {
         cout << "\tROW:" << setw(5) << (idxY + 1) ;

         for (idxZ = 0; idxZ < SEATS_IN_ROW; ++idxZ)
         {       
            cout << setw(4) << seatPrices[idxX][idxY][idxZ];
         }
         cout << "\n";
      }       
   }
}

/* **********************************************************
   Definition: viewStatsAudit

   This function accepts seats[][][] and seatPrices[][][] as
   its argument. It displays the number of booked and free
   seats, and the amount of sales of tickets.
   ********************************************************** */

void viewStatsAudit(auditorium seats, prices seatPrices, double total)
{
   /* Variables: Index x, Index y, Index z */
   int idxX = 0,
       idxY = 0,
       idxZ = 0;

   /* Variables: Row number, Count free seats, Count booked
                 seats */
   int rowNum = 0,
       cntFree = 0,
       cntFull = 0;

    for (idxX = 0; idxX < SECTIONS; idxX++)
    {
       for (idxY = 0; idxY < ROWS_PER_SECTION; idxY++)
       {
          for (idxZ = 0; idxZ < SEATS_IN_ROW; idxZ++)
          {
             seats[idxX][idxY][idxZ] == FREE ? cntFree += 1 :
                cntFull += 1;
          }
       }
    }

   /* Display the sales statistics */
   cout << "\n\t\tSALES STATS - TOTAL:\n\n"
        << "\t\tFree Seats: " << cntFree
        << "\n\t\tBooked Seats: " << cntFull
        << "\n\t\tSales Total: GBP " << (total) << "\n\n";
}

/* **********************************************************
   Definition: viewStatsRow

   This function accepts seats[][][] and seatPrices[][][] as
   its argument. It displays the number of booked and free
   seats, and the amount of sales of tickets for a whole row
   the user can select.
   ********************************************************** */

void viewStatsRow(auditorium seats, prices seatPrices)
{
   /* Variables: Index x, Index y, Index z */
   int idxX = 0,
       idxY = 0,
       idxZ = 0;

   /* Variables: Row number, Count free seats, Count booked
                 seats */
   int rowNum = 0,
       cntFree = 0,
       cntFull = 0;

   /* Variable: Total sales in row */
   double totalSalesRow = 0.0;

   cout << "\n\t\tPlease enter a row number (1 through 15) to "
        << "view per-row statistics: ";
   cin >> rowNum;

   /* Validate Input */
   while (rowNum < 0 || rowNum > SEATS_IN_ROW * 3)
   {
      cout << "\n\t\tInvalid Input!\n"
           << "\t\tPlease enter a row number (1 through 15) to "
           << "view per-row statistics: ";
      cin >> rowNum;
   }

   /* Count and accumulate free and booked seats */
   for (idxZ = 0; idxZ < SEATS_IN_ROW; idxZ++)
   {
            seats[idxX][rowNum - 1][idxZ] == FREE ? cntFree += 1 :
               seats[idxX][rowNum - 1][idxZ];

            seats[idxX][rowNum - 1][idxZ] == BOOKED ? cntFull += 1 :
               seats[idxX][rowNum - 1][idxZ];

            totalSalesRow = seatPrices[idxX][rowNum - 1][idxZ] * cntFull;
   }

   /* Display per row statistics */
   cout << "\n\t\tSALES STATS - ROW:\n\n"
        << "\t\tRow Number: " << rowNum
        << "\n\t\tFree Seats: " << cntFree
        << "\n\t\tBooked Seats: " << cntFull
        << "\n\t\tSales Row # " << rowNum << ": GBP "
        << totalSalesRow <<  "\n";
}

/* **********************************************************
   Definition: booking

   This function accepts seats[][][] and seatPrices[][][] as
   its argument. It allows a user to enter the number of
   seats he or she wishes to book. If the process has been
   completed, the booking information is displayed, and the
   total sum is returned.
   ********************************************************** */

double booking(auditorium seats, prices seatPrices, int &rowNum,
               int &seatNum)
{
   /* Variable: Is free */
   bool isFree = false;

   /* Variables: Index x, Index y, Index z, Count (loop counter),
                 Number of seats */
   int idxX = 0,
       idxY = 0,
       idxZ = 0,
       count = 0,
       numSeats = 0;

   /* Variable: Checkout */
   char checkout = ' ';

   /* Variables: Subtotal, Total (accumulators) */
   double subTotal = 0.0,
          total = 0.0;

   cout << "\n\t\tHow many seats do you wish to book? ";
   cin >> numSeats;

   /* While count is lower than the number of seats the user wishes
      to book, he or she is asked to enter row and seat numbers. */
   while (count < numSeats)
   {
      cout << "\n\t\tEnter Row Number: ";
      cin >> rowNum;

      cout << "\t\tEnter Seat Number: ";
      cin >> seatNum;

      /* Validate Input */
      while (rowNum <= 0 || rowNum > ROWS_PER_SECTION * 3 || seatNum <= 0 ||
             seatNum > SEATS_IN_ROW)
      {
         cout << "\n\t\tInvalid Input!\n";

         cout << "\n\t\tEnter Row Number: ";
         cin >> rowNum;

         cout << "\t\tEnter Seat Number: ";
         cin >> seatNum;
      }

      /* Validate Input - This call checks whether the row and seat
         number entered is still free */
      while (isFree = checkAv(seats, idxX, rowNum, seatNum) == false)
      {
         cout << "\n\t\tEnter Row Number: ";
         cin >> rowNum;

         cout << "\t\tEnter Seat Number: ";
         cin >> seatNum;
      }

      /* The subtotal of every order is displayed during input, and accumulated
         in the variable subTotal */
      cout << "\n\t\tSubtotal: GBP "
           << (subTotal += seatPrices[idxX][rowNum - 1][seatNum - 1]) << "\n";

      /* The user is asked to enter Y or y to accept the order. If he or she
         enters Y or y, the seat will be booked and the position in the array
         is filled, else the seat remains free and the function exits. */
      cout << "\n\t\tProceed? (Y)es | (N)o? ";
      cin >> checkout;

      if (checkout == 'Y' || checkout == 'y')
      {
        seats[idxX][rowNum - 1][seatNum - 1] = BOOKED;

         total = subTotal;
      }
     
      count += 1;
   }

   /* Display the order information */
   cout << "\n\n\t\tBOOKING INFORMATION:\n\n"
        << "\t\tNumber of seats: " << numSeats
        << "\n\t\tTotal: GBP " << (total);
   cout << "\n\n\t\tThe Aldwych Theater Company Thanks You For Your Order!\n\n";

   return total;
}

/* **********************************************************
   Definition: checkAv

   This function accepts auditorium[][][] as its argument.

   It determines whether a seat position entered by the user
   is booked or free and returns the result.
   ********************************************************** */

bool checkAv(auditorium seats, int idxX, int rowNum, int seatNum)
{
   /* Variable: Is free */
   bool isFree = false;

   /* This ternary determines whether the row and seat number are
      free or not. */
   seats[idxX][rowNum - 1][seatNum - 1] == BOOKED ?
      cout << "\n\t\tBOOKED\n", isFree = false :
                                isFree = true;

   return isFree;
}

Example Output:









No comments:

Post a Comment