-1

I'm given an assignment where the user enters the number of seats they would like to book for a trip. After, I set an array of the seats all to false, as they are empty. Then depending on the number of seats the user wants to reserve, the program will output a boarding pass with the seat number. And the output for the boarding passes cannot have the same seat numbers, as they are either empty or not.

My code is working great except for the little snippet you see below. As you see I set all the seats for the club and economy classes to false. Then I prompt the user to enter the seats they would like to reserve. The issue I'm having is at the bottom of the code, since there are 5 club seats, if I wanted to reserve 5 club seats, it should output the 5 boarding passes with the distinct seat numbers. But for some reason it doesn't output all 5 seats, for example, if I enter that I would like 5 seats, and that they are all club seats, my program outputs:

Club Pass: Seat 1
Club Pass: Seat 1
Club Pass: Seat 3
Club Pass: Seat 2
Club Pass: Seat 1

I'm new to arrays and I know that subscripts begins at 0, I was thinking that maybe I needed to subtract 1 from the Math.random line below. I understand the issue is most likely regarding the final snippet of the code and the Math.Random line but I'm not sure what is exactly causing this error.**

import java.util.Scanner;
public class MyClass
{
public static void main(String args[])
{
    Scanner input = new Scanner (System.in);
    
    System.out.println ("Welcome to the new bullet train from Beefalo Bay Transportation Company.");
    
    System.out.println ("Our new bullet train has 20 seats, 5 club, and 15 economy seats.");
    
    System.out.println ("Would you like to make a booking? If so enter true, if not enter false.");
    
    boolean wantToReserve = input.nextBoolean();
        
        while (wantToReserve == false)
        {
            System.out.println ("You entered false. Would you like to make a reservation?");
        
            wantToReserve = input.nextBoolean();
        
            if (wantToReserve == false)
            {
                System.out.println ("You may close the program.");
            }
        }
    System.out.println ("How many seats would you like to book?");

    System.out.println ("Please note we only have 20 seats, 5 club and 15 economy.");

    System.out.println ("If you would like more than 20 seats, please execute the program multiple times.");

    int numberOfSeats = input.nextInt();
    
        while (numberOfSeats > 20 | numberOfSeats <= 0){
            System.out.println ("You entered a value greater than 20 or less than 0.");

            System.out.println ("You must modify the seats you would like to book, as we only have 20 seats.");

            System.out.println ("If you would like more than 20 seats, please execute the program multiple times.");

            numberOfSeats = input.nextInt();
        }
        
    boolean clubSeating [] = {false, false, false, false, false};
    
    boolean economySeating [] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};

    System.out.println ("How many club seats would you like?");

    int numberOfClub = input.nextInt();
    
    System.out.println ("How many economy seats would you like?");
    
    int numberOfEconomy = input.nextInt();

        while (numberOfClub + numberOfEconomy != numberOfSeats || numberOfEconomy > 15 || numberOfClub > 5 || numberOfEconomy < 0 && numberOfClub < 0 ){
            System.out.println ("At least one of the previous inputs were not allowed. Note that we have 5 club and 15 economy seats. Please re-enter.");
        
            System.out.println ("How many club seats would you like?");
        
            numberOfClub = input.nextInt();
        
            System.out.println ("How many economy seats would you like?");
        
            numberOfEconomy = input.nextInt();
        }
        
        
        for (int j = 0; j < numberOfClub ; j++){
        
            int seatForClub1 = (int) (Math.random()*(numberOfClub));
            
            clubSeating [seatForClub1] = true;
            
            int seatForClub = (int) (Math.random()*(numberOfClub));

            if (clubSeating [seatForClub] == false){
                clubSeating [seatForClub] = true;                       
                System.out.println ("Boarding Pass: Seat  " + seatForClub);
            }
                
            if (clubSeating [seatForClub] == true){
                seatForClub = (int) (Math.random()*(numberOfClub)); 
                System.out.println ("Boarding Pass: Seat  " + seatForClub);
            }
        }
    }        
        
}
Somansh Reddy
  • 125
  • 2
  • 13
  • Not necessarily, the issue is that with my program, is that although it's generating random numbers. My program doesn't recognize when it's one that's been generated already or whether it's new, either way my program prints them out. Sorry! – William Wang Sep 04 '20 at 21:10
  • 1
    And that is what the linked question addresses, please read it again. There are several useful answers to choose from – Joakim Danielson Sep 04 '20 at 21:12
  • I'm sorry to say this, but most of the syntax in the post is extremely foreign to me. I have just started an intro to Java course a few weeks ago. I'm trying to understand it, but if someone could help in in this specific situation that would be great, if not I understand. Either ways thank you for referring me to the post. – William Wang Sep 04 '20 at 21:20

1 Answers1

0

You are right about the issue being about Math.Random(). This just returns a random number but it may be repeating when rounded off. So is highly likely that when you multiply this with the number of seats you may get the same value again.

For ex: One invocation of Math.Random() may result in 0.8 and another might result on 0.71. Both of these when multiplied by 3 ( number of club seats ) would return 2 Because when you typecast to an int, the decimal part is dropped.

So if you loop 3 times, and you are unfortunate enough to get all 2s, then you would have only booked one seat.

One workaround is to increment the loop counter only when the seat is booked.

       for (int j = 0; j < numberOfClub; ) {
            int seatForClub = (int) (Math.random() * (numberOfClub));

            if (clubSeating[seatForClub] == false) {
                clubSeating[seatForClub] = true;
                System.out.println("Boarding Pass: Seat  " + seatForClub);
                j++;
            }
        } 

But the disadvantage of getting the same seat number remains ( if Math.Random() gives values that keep returning 2 when multiplied with number of club seats ) so you may end looping as many times as it takes to generate all the values.

There is an edge case. If there are no empty seats remaining then the loop would run indefinitely. So we need to check for the number of seats remaining as well. If there are 10 total club seats, and the user requests for 12. Then once the array of 10 seats all become true ( so all seats are occupied ), the loop would have still been running trying to reach the count of 12 ( this is the number of seats requested ). Once we add a check for number of seats remaining, we no longer have to worry about the indefinite loop. So basically, if the number of requested seats is greater than the number of available / remaining seats when we reach this code snippet then the code would fail.

        int numberOfClubSeatsRemaining = totalNumberOfClubSeats; // initialize to total number of seats 
        
      
        for (int j = 0; numberOfClubSeatsRemaining > 0 && j < numberOfClub; ) {
             int seatForClub = (int) (Math.random() * (numberOfClub));
 
             if (clubSeating[seatForClub] == false) {
                 clubSeating[seatForClub] = true;
                 System.out.println("Boarding Pass: Seat  " + seatForClub);
                 j++;
                 numberOfClubSeatsRemaining--;
             }
         }

There are better ways to get a random value in Java. You can refer to this How do I generate random integers within a specific range in Java?

You can also generate a random list using Collections.shuffle() and iterate over the first n elements on this ( where n would be the number of club seats in this case ). But if the goal of this particular exercise is for beginners to understand the algorithm and to do it without any built in functions / Collections framework, then this approach wouldn't be right for you.

Somansh Reddy
  • 125
  • 2
  • 13
  • 1
    Thank you so much!! – William Wang Sep 04 '20 at 21:40
  • I had kept the answer to the point just to address the random number generation issue but you can also clean up your code a bit. I didn't understand why you had called `Math.random()` thrice within each iteration of the for loop. Also, you can initialize the boolean arrays in a for loop rather than hard-coding the entire list. In fact, I recommend that you soon move toward learning and implementing the Collections framework as it is a very critical part of Java. – Somansh Reddy Sep 04 '20 at 21:45
  • @WilliamWang Sorry, I had edited the answer to address an edge case but the posted answer did not go through. Just submitted it again. Please take a look at the edge case. – Somansh Reddy Sep 04 '20 at 22:00
  • 1
    No problem. Thank you for all the help. – William Wang Sep 05 '20 at 22:03