Home > front end >  Looping Frustration while learning Java
Looping Frustration while learning Java

Time:10-14

all! I'm a hobbyist at best when it comes to programming. I've really hunkered down and finished a few tutorials such as sololearn, W3, etc. I'm writing this program to try to apply some things I've been seeing on Youtube. So I've tried to write a version of FizzBuzz with minimal research. I have the following code all in their separate files.

   import java.util.Scanner;

public class FizzBuzzMosh {
  public static void main(String[] arg) {
    char yesno;
    System.out.print("Would you like to play FizzBuzz? \\n (Y)es or (N)o: ");
    Scanner yesNoInput = new Scanner(System.in);
    yesno = yesNoInput.next().charAt(0);
    FizzBuzzYesNo play = new FizzBuzzYesNo();
    play.fizzBuzzYesNo(yesno);
  } // Ends main
}// Ends FizzBuzzMosh


    import java.util.Scanner;

public class FizzBuzzYesNo {
    public void fizzBuzzYesNo(char yesno) {
        int passNum = 0;
        if (yesno == 'Y' || yesno == 'y') {
            System.out.print(
                    "Ok. Let's play. Give me a number. I will say Fizz, Buzz, or Pop the number back to you: ");
            Scanner numInput = new Scanner(System.in);
            passNum = numInput.nextInt();
            FizzBuzzFunc playInput = new FizzBuzzFunc();
            playInput.fizzBuzzFunc(passNum);
        } else {
            System.out.println("Goodbye");
        }
    }
}

import java.util.Scanner;

public class FizzBuzzFunc {

    public void fizzBuzzFunc(int passNum) {
        char confirm = 'N';
        int counter = 0;
        do {
            counter  ;
            if ((passNum % 3) == 0 && (passNum % 5) == 0) {
                System.out.println("FizzBuzz");

            } else if (((passNum % 3) == 0)) {
                System.out.println("Buzz");

            } else if (((passNum % 5) == 0)) {
                System.out.println("Fizz");

            } else {
                System.out.println("POP! "   passNum);
            }

            System.out.print("Would you like to play again? \\n (Y)es or (N)o: ");
            Scanner confirmScan = new Scanner(System.in);
            confirm = confirmScan.next().charAt(0);
            if (confirm == 'Y' || confirm == 'y') {
                System.out.print("Ok, Give me another number: ");
                FizzBuzzFunc playagain = new FizzBuzzFunc();
                Scanner newNum = new Scanner(System.in);
                passNum = newNum.nextInt();
                playagain.fizzBuzzFunc(passNum);
            }

        } while (confirm == 'Y' || confirm == 'y');

        System.out.println("You played "   counter   " times.");
        System.out.println("Ok. Goodbye");

    }
}// Ends FizzBuzzFunc 

My question is, I'm getting this output from the terminal:

Would you like to play FizzBuzz? 
(Y)es or (N)o: y
Ok. Let's play. Give me a number. I will say Fizz, Buzz, or Pop the number back to you: 5
Fizz
Would you like to play again?
 (Y)es or (N)o: y
Ok, Give me another number: 3
Buzz
Would you like to play again?
 (Y)es or (N)o: y
Ok, Give me another number: 15
FizzBuzz
Would you like to play again?
 (Y)es or (N)o: n
You played 1 times.
Ok. Goodbye
FizzBuzz
Would you like to play again?
 (Y)es or (N)o:

It's like the FizzBuzzFunc is looping for some reason. If I play 1 time, the game reacts as normal, says "goodbye" and exits. However, if I play more than once, the game will continuosly loop and won't end after the user presses anything other than 'Y' or 'y'. Any help would be very useful at this stage of the game.

CodePudding user response:

One of the last lines in your paste is this:

playagain.fizzBuzzFunc(passNum);

This means your fizzBuzzFunc is calling itself. That's called a recursive function. This does not mean: Restart the function. This means: Whilst remember that this 'take' of the function is still running, run another one. The new one gets all new variables, and when it finishes (gets to the end, or, returns), we go back to 'the old one'.

So, I play once, hit 'Y', and this causes a new fizzBuzzFunc to run whilst the old one is still there, at that line, waiting for the new fBF to finish.

then, in the new one, I press N. that one finishes. But that just means we go back to the original one, which dutifully continues right where it left off. It gets to the while(confirm == 'Y' || confirm == 'y'); part and simply loops again. After all, confirm is indeed Y. Remember, every 'version' of the fBF function gets its own variables. The fBF you called (the 'inner' FBF) had confirm = N, but the outer one did not. So, it loops, and you get your behaviour.

You've built a loop-in-a-loop. This function loops, by way of recursion:

int add(int a, int b) {
  System.out.println("Mark!");
  if (b == 0) return a;
  return 1   add(a, b - 1);
}

There's no while or for loop in sight and yet, that loops. You can trivially witness it looping by noticing that Mark! is printed. Call add(5, 10) and it'll print 10 times.

Your code has a while loop, and it recurses. So that's a loop in a loop, which isn't what you wanted.

Pick a side. Either recurse, or while loop. From the setup, I think the right answer is: Keep the while loop, ditch the recursion. Just.. don't call playagain.fizzBuzzFunc - let the while loop do its thing.

CodePudding user response:

as your code, when you enter something not Y or y, you create a new fizzBuzzFunc instance and it will start a new fizzBuzzFunc method. IMO, if you just want to continue the game when a client enter Y or y, you don't just need the if (confirm == 'Y' || confirm == 'y') { block. BTW, you can pick Scanner confirmScan = new Scanner(System.in); out do block. Eventually the do {} while block may look like this:

Scanner confirmScan = new Scanner(System.in);
do {
    counter  ;
    if ((passNum % 3) == 0 && (passNum % 5) == 0) {
        System.out.println("FizzBuzz");
    } else if (((passNum % 3) == 0)) {
        System.out.println("Buzz");
    } else if (((passNum % 5) == 0)) {
        System.out.println("Fizz");
    } else {
        System.out.println("POP! "   passNum);
    }
    System.out.print("Would you like to play again? \\n (Y)es or (N)o: ");
    confirm = confirmScan.next().charAt(0);
    if (confirm == 'Y' || confirm == 'y') {
        System.out.print("Ok, Give me another number: ");
    }
} while (confirm == 'Y' || confirm == 'y');
  • Related