Advertisement
Guest User

Tickets

a guest
Sep 18th, 2019
8,407
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.47 KB | None | 0 0
  1. /**
  2.  * Name: Dien Kim Tran
  3.  * NetID: DKT180000
  4.  * Date: 9/17/2019
  5.  *
  6.  * Submission for Project 1: Movie Ticket Reservation System
  7.  */
  8.  
  9. package Tickets;
  10.  
  11. import java.io.*;
  12. import java.util.Scanner;
  13. import java.util.stream.*;
  14.  
  15. /**
  16.  * A class for storing auditoriums.
  17.  */
  18. class Auditorium {
  19.     // Store the file name of this instance's auditorium.
  20.     private String fileName;
  21.  
  22.     // 2D char array containing the actual auditorium seats.
  23.     public char[][] seats;
  24.  
  25.     // Ticket prices for adults, children and seniors
  26.     public static final double PRICE_ADULT = 10.00;
  27.     public static final double PRICE_CHILD = 5.00;
  28.     public static final double PRICE_SENIOR = 7.50;
  29.  
  30.     /**
  31.      * Constructor, takes file name and dimensions of seat grid
  32.      *
  33.      * @param fileName The file name of the auditorium
  34.      * @param MAX_ROWS The number of rows of the seat grid
  35.      * @param MAX_COLS The number of columns of the seat grid
  36.      */
  37.     Auditorium(String fileName, char[][] seats) {
  38.         // Store auditorium file name
  39.         this.fileName = fileName;
  40.  
  41.         // Allocate the seats grid
  42.         this.seats = seats;
  43.     }
  44.  
  45.     /**
  46.      * Returns the file name of the instance's auditorium.
  47.      *
  48.      * @return the file name of the auditorium
  49.      */
  50.     public String getFileName() {
  51.         return fileName;
  52.     }
  53.  
  54.     /**
  55.      * Reads in the auditorium 2D char array from a given auditorium file.
  56.      *
  57.      * @param auditoriumFile a `File` of auditorium seats
  58.      * @return A 2D char array of seats from the file
  59.      */
  60.     static char[][] readSeats(File auditoriumFile) throws Exception {
  61.         // Used to initialize the `seats` array
  62.         int numRows = 0, numCols = 0;
  63.  
  64.         // Set up a Scanner applied to the file
  65.         try (Scanner input = new Scanner(auditoriumFile)) {
  66.             // Get the number of columns
  67.             if (input.hasNext()) {
  68.                 numCols = input.nextLine().length();
  69.                 numRows = 1; // we read in a row; set it to 1
  70.             }
  71.  
  72.             // Get the number of rows by reading until EOF
  73.             while (input.hasNext()) {
  74.                 input.nextLine();
  75.                 ++numRows;
  76.             }
  77.         }
  78.  
  79.         // Initialize the `seats` array
  80.         char[][] seats = new char[numRows][numCols];
  81.  
  82.         // Populate `seats`
  83.         try (Scanner input = new Scanner(auditoriumFile)) {
  84.             // Read in row
  85.             for (int row = 0; row < numRows; ++row) {
  86.                 seats[row] = input.nextLine().toCharArray();
  87.             }
  88.         }
  89.  
  90.         // Done, return `seats`
  91.         return seats;
  92.     }
  93. }
  94.  
  95. public class Main {
  96.     /**
  97.      * Takes a 2D char array representing a seat layout and displays it in a
  98.      * formatted fashion.
  99.      *
  100.      * @param seats The seat layout, as a 2D char array
  101.      */
  102.     private static void displaySeatLayout(char[][] seats) {
  103.         // Print the column axis
  104.         System.out.print("  ");
  105.         for (int col = 0; col < seats[0].length; ++col) {
  106.             System.out.print((char) Character.toUpperCase(('A' + col)));
  107.         }
  108.         System.out.println();
  109.  
  110.         // Print seat rows
  111.         for (int row = 0; row < seats.length; ++row) {
  112.             System.out.print("" + (row + 1) + " ");
  113.             for (int col = 0; col < seats[row].length; ++col) {
  114.                 switch (seats[row][col]) {
  115.                 case '.':
  116.                     System.out.print('.');
  117.                     break;
  118.                 default:
  119.                     System.out.print('#');
  120.                     break;
  121.                 }
  122.             }
  123.             System.out.println();
  124.         }
  125.     }
  126.  
  127.     /**
  128.      * Displays information about booked seats for a given auditorium
  129.      * @param aud The auditorium to display information about
  130.      */
  131.     private static void displayReport(Auditorium aud) {
  132.         System.out.println("Report on auditorium \"" + aud.getFileName() + "\"");
  133.  
  134.         // Flatten seats
  135.         char[] flatSeats = new char[aud.seats.length * aud.seats[0].length]; // size = numRows * numCols
  136.         for (int row = 0; row < aud.seats.length; ++row) {
  137.             for (int col = 0; col < aud.seats[row].length; ++col) {
  138.                 flatSeats[aud.seats[row].length * row + col] = aud.seats[row][col];
  139.             }
  140.         }
  141.  
  142.         // Compute all required values
  143.         long adultTicketsSold = 0, childTicketsSold = 0, seniorTicketsSold = 0;
  144.         for (int index = 0; index < flatSeats.length; ++index) {
  145.             switch (flatSeats[index]) {
  146.             case 'A':
  147.                 ++adultTicketsSold;
  148.                 break;
  149.             case 'C':
  150.                 ++childTicketsSold;
  151.                 break;
  152.             case 'S':
  153.                 ++seniorTicketsSold;
  154.                 break;
  155.             }
  156.         }
  157.         double totalTicketSales = Auditorium.PRICE_ADULT * adultTicketsSold
  158.                                 + Auditorium.PRICE_CHILD * childTicketsSold
  159.                                 + Auditorium.PRICE_SENIOR * seniorTicketsSold;
  160.  
  161.         // Display them
  162.         System.out.println("Adult tickets sold: " + adultTicketsSold);
  163.         System.out.println("Child tickets sold: " + childTicketsSold);
  164.         System.out.println("Senior tickets sold: " + seniorTicketsSold);
  165.         System.out.println("Total tickets sold: " + (adultTicketsSold + childTicketsSold + seniorTicketsSold));
  166.         System.out.printf("Total ticket sales: $%.2f\n", totalTicketSales);
  167.     }
  168.  
  169.     private static int printGetMenuChoice(Scanner input) {
  170.         System.out.println("1. Reserve Seats\n2. Exit");
  171.         System.out.print("Type desired menu entry and press Enter: ");
  172.         int choice;
  173.         choice = input.nextInt();
  174.         return choice;
  175.     }
  176.  
  177.     /**
  178.      * Checks whether the desired seats on the `row`-th row, starting from
  179.      * [row][col] and ending at [row][col + numSeats - 1], are available. All
  180.      * coordinates must be zero-based.
  181.      *
  182.      * @param seatRow  The row of seats
  183.      * @param col      The index of the column where desired seats are located
  184.      * @param numSeats The number of seats to query
  185.      * @return A boolean value, true if such seats are available to book, false if
  186.      *         not
  187.      */
  188.     private static boolean queryAvailable(char[] seatRow, int col, int numSeats) {
  189.         // The last seat in the sequence must not be out-of-bounds
  190.         if (col + numSeats > seatRow.length)
  191.             return false;
  192.  
  193.         // Loop along desired seats until we find one non-available seat
  194.         for (int index = 0; index < numSeats; ++index) {
  195.             if (seatRow[col + index] != '.') {
  196.                 return false;
  197.             }
  198.         }
  199.         return true;
  200.     }
  201.  
  202.     /**
  203.      * Writes the seat layout of an `Auditorium` object to a file.
  204.      *
  205.      * @param aud the auditorium object of which seat layout is to be written
  206.      * @throws Exception
  207.      */
  208.     private static void writeSeatLayout(Auditorium aud) throws Exception {
  209.         try (PrintWriter output = new PrintWriter(new File(aud.getFileName()))) {
  210.             for (int index = 0; index < aud.seats.length; ++index) {
  211.                 output.println(new String(aud.seats[index]));
  212.             }
  213.         }
  214.     }
  215.  
  216.     /**
  217.      * Finds the best available seats, biased towards the middle of the row, towards
  218.      * the left, then towards the right
  219.      *
  220.      * @param seatRow  The row of the seats the user wants to book
  221.      * @param numSeats The number of seats to book
  222.      * @return -1 if no seats available on this row, or the starting column index if
  223.      *         available
  224.      */
  225.     private static int findBestAvailableSeats(char[] seatRow, int numSeats) {
  226.         // Cache these values, to be used for computation
  227.         int seatSequenceLengthMiddle = numSeats / 2, rowLengthMiddle = seatRow.length / 2;
  228.  
  229.         // Trivial case: Check if `seatRow.length < numSeats`, return -1 if true
  230.         if (seatRow.length < numSeats)
  231.             return -1;
  232.  
  233.         // We check from the middle of the row, then query whether the seat sequence
  234.         // shifted by 1 to the left are available, until we get to the start of the row
  235.         for (int offset = 0; offset < rowLengthMiddle - seatSequenceLengthMiddle + 1; ++offset) {
  236.             if (queryAvailable(seatRow, rowLengthMiddle - seatSequenceLengthMiddle - offset, numSeats)) {
  237.                 return rowLengthMiddle - seatSequenceLengthMiddle - offset;
  238.             }
  239.         }
  240.  
  241.         // Do the same as above but shift to the right instead
  242.         for (int offset = 1; offset < (seatRow.length - rowLengthMiddle + seatSequenceLengthMiddle - numSeats
  243.                 + 1); ++offset) {
  244.             if (queryAvailable(seatRow, rowLengthMiddle - seatSequenceLengthMiddle + offset, numSeats)) {
  245.                 return rowLengthMiddle - seatSequenceLengthMiddle + offset;
  246.             }
  247.         }
  248.  
  249.         // If we get here, we obviously haven't returned the starting position of the
  250.         // first available seat yet, so return -1
  251.         return -1;
  252.     }
  253.  
  254.     /**
  255.      * Returns a new row with seats booked.
  256.      *
  257.      * @param seatRow   Current row
  258.      * @param start     Starting column where seats are booked
  259.      * @param seatTypes Encapsulates adult, child, and senior tickets
  260.      * @return A `char` array with committed changes
  261.      */
  262.     private static char[] bookSelectedSeats(char[] seatRow, int start, int[] seatTypes) {
  263.         for (int index = 0; index < seatTypes[0]; ++index) {
  264.             seatRow[start + index] = 'A';
  265.         }
  266.         for (int index = seatTypes[0]; index < seatTypes[0] + seatTypes[1]; ++index) {
  267.             seatRow[start + index] = 'C';
  268.         }
  269.         for (int index = seatTypes[0] + seatTypes[1]; index < seatTypes[0] + seatTypes[1] + seatTypes[2]; ++index) {
  270.             seatRow[start + index] = 'S';
  271.         }
  272.         return seatRow;
  273.     }
  274.  
  275.     public static void main(String[] args) throws Exception {
  276.         // Create a null reference to an `Auditorium` array.
  277.         Auditorium[] auditoriums;
  278.  
  279.         // Read from current directory
  280.         File currentDir = new File(".");
  281.  
  282.         // Filter out files that end with ".txt"
  283.         File[] auditoriumFiles = Stream.of(currentDir.listFiles())
  284.                 .filter((txtFile) -> txtFile.getName().endsWith(".txt")).toArray(File[]::new);
  285.  
  286.         // Allocate enough space for all auditoriums
  287.         auditoriums = new Auditorium[auditoriumFiles.length];
  288.  
  289.         // Instantiate all auditoriums
  290.         for (int index = 0; index < auditoriums.length; ++index) {
  291.             auditoriums[index] = new Auditorium(auditoriumFiles[index].getName(),
  292.                     Auditorium.readSeats(auditoriumFiles[index]));
  293.         }
  294.  
  295.         // Ask the user for which file to choose
  296.         System.out.println("Auditorium files found:");
  297.         for (int index = 0; index < auditoriumFiles.length; ++index) {
  298.             System.out.println("" + (index + 1) + ": " + auditoriumFiles[index].getName());
  299.         }
  300.         int auditoriumIndex;
  301.         System.out.print("Type the number corresponding to the auditorium you want: ");
  302.  
  303.         try (Scanner input = new Scanner(System.in)) {
  304.             auditoriumIndex = input.nextInt() - 1;
  305.             while (auditoriumIndex < 0 || auditoriumIndex >= auditoriums.length) {
  306.                 System.out.println("Invalid file number. Input again.");
  307.                 System.out.print("Type the number corresponding to the auditorium you want: ");
  308.                 auditoriumIndex = input.nextInt() - 1;
  309.             }
  310.  
  311.             // Store current auditorium to a variable so it's easier to work with
  312.             // and write out
  313.             Auditorium currentAuditorium = auditoriums[auditoriumIndex];
  314.  
  315.             System.out.println("You chose file number " + (auditoriumIndex + 1) + ", which is "
  316.                     + currentAuditorium.getFileName() + "\n");
  317.  
  318.             // We now perform our tasks on the file at `auditoriumFiles[auditoriumIndex]`.
  319.             // MAIN LOGIC LOOP
  320.             int menuChoice = 2;
  321.             do {
  322.                 menuChoice = printGetMenuChoice(input);
  323.                 System.out.println();
  324.                 switch (menuChoice) {
  325.                 // There is no other case than case 1.
  326.                 case 1:
  327.                     // User wants to reserve seats
  328.                     // Print current seat layout
  329.                     System.out.println("Current seat layout:");
  330.                     displaySeatLayout(currentAuditorium.seats);
  331.                     System.out.println();
  332.  
  333.                     // Prompt for needed information
  334.                     System.out.println("You can book multiple seats on the same row.");
  335.                     System.out.print("Row of your desired seats: ");
  336.                     int bookingRow = input.nextInt();
  337.                     System.out.print("Starting seat letter: ");
  338.                     int bookingColumn = Character.toUpperCase(input.next().charAt(0)) - 'A' + 1;
  339.                     System.out.print("Number of adult tickets: ");
  340.                     int numAdultTickets = input.nextInt();
  341.                     System.out.print("Number of child tickets: ");
  342.                     int numChildTickets = input.nextInt();
  343.                     System.out.print("Number of senior tickets: ");
  344.                     int numSeniorTickets = input.nextInt();
  345.                     System.out.println();
  346.  
  347.                     // Compute the number of tickets to book
  348.                     int numSeats = numAdultTickets + numChildTickets + numSeniorTickets;
  349.  
  350.                     // Query if they are available
  351.                     if (!queryAvailable(currentAuditorium.seats[bookingRow - 1], bookingColumn - 1, numSeats)) {
  352.                         System.out.println(
  353.                                 "The seats you requested are unavailable. Finding the next best available seats.");
  354.  
  355.                         // Find the best available seats
  356.                         int bestAvailableColumn = findBestAvailableSeats(currentAuditorium.seats[bookingRow - 1],
  357.                                 numSeats);
  358.                         if (bestAvailableColumn == -1) {
  359.                             System.out.println("No seats available this row.\n");
  360.                         } else {
  361.                             // Ask the user if they want these seats
  362.                             System.out.print("Best available seats: ");
  363.                             for (int col = bestAvailableColumn; col < bestAvailableColumn + numSeats; ++col) {
  364.                                 System.out.print("" + bookingRow + (char) (col + 'A'));
  365.                                 if (col != numSeats - 1) {
  366.                                     System.out.print(' ');
  367.                                 }
  368.                             }
  369.                             System.out.print("\nDo you want these seats? (y/n) ");
  370.                             char bestAccepted = input.next().charAt(0);
  371.                             if (bestAccepted == 'y') {
  372.                                 currentAuditorium.seats[bookingRow - 1] = bookSelectedSeats(
  373.                                         currentAuditorium.seats[bookingRow - 1], bestAvailableColumn,
  374.                                         new int[] { numAdultTickets, numChildTickets, numSeniorTickets });
  375.  
  376.                                 System.out.println("\nChanges written.\n");
  377.  
  378.                                 // Save layout to file
  379.                                 writeSeatLayout(currentAuditorium);
  380.                             } else {
  381.                                 // User does not want these seats, move on
  382.                                 System.out.println();
  383.                             }
  384.                         }
  385.                     } else {
  386.                         // Seats available -- book them
  387.                         currentAuditorium.seats[bookingRow - 1] = bookSelectedSeats(
  388.                                 currentAuditorium.seats[bookingRow - 1], bookingColumn - 1,
  389.                                 new int[] { numAdultTickets, numChildTickets, numSeniorTickets });
  390.  
  391.                         System.out.println("\nChanges written.\n");
  392.  
  393.                         // Save layout to file
  394.                         writeSeatLayout(currentAuditorium);
  395.                     }
  396.                 }
  397.             } while (menuChoice != 2);
  398.  
  399.         }
  400.  
  401.         // Print report on all auditoriums
  402.         for (Auditorium aud : auditoriums) {
  403.             displayReport(aud);
  404.             System.out.println();
  405.         }
  406.  
  407.         // Done.
  408.     }
  409. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement