-1

Here is the particular function I am having trouble with.

  static boolean check(double money)
  {
    String scont, yes = "yes", no = "no";
    boolean bcont;
    if (money == 0) {
      System.out.println("You are broke and can no longer play.");
      bcont = false;
      return bcont;
    }
    System.out.println("You have " + form.format(money) + " left.");
    System.out.println("Would you like to continue playing? (Yes or no?)");
    scont = in.nextLine();
    if (scont.equalsIgnoreCase(yes)) {
      bcont = true;
      return bcont;
    }
    else if (scont.equalsIgnoreCase(no)) {
      bcont = false;
      return bcont;
    }
    else {
      System.out.println("Invalid answer.");
      bcont = check(money);
      return bcont;
    }
  }

Here is the whole program.

import java.util.Random;
import java.util.Scanner;
import java.text.*;

public class JS4B
{
  static Scanner in = new Scanner(System.in);
  static DecimalFormat form = new DecimalFormat("$#.00");

  public static void main(String [] args)
  {
    int roundnum = 1;
    double beginmoney, money;
    boolean cont;

    intro();
    beginmoney = hmmoney();
    money = beginmoney;

    do{
      System.out.println("\nRound " + roundnum + ":");
      System.out.println("-------\n");
      money = round(money);
      cont = check(money);
    }while(cont == true);

    if (money > beginmoney) {
      System.out.println("Congratulations! You have completed " + 
    rounds(roundnum) + " and ended up with more money than you started!");
    }
    else if (money == beginmoney) {
      System.out.println("You broke even! You have completed " + 
    rounds(roundnum) + ".");
    }
    else if (money != 0) {
      System.out.println("You have less money than you started with, but " + 
    "at least you didn't lose it all. You completed " + rounds(roundnum) + ".");
    }
    else {
      System.out.println("You have completed " + rounds(roundnum) + ".");
    }

    System.out.println("You started with " + form.format(beginmoney) + 
    " and ended with " + form.format(money));
  }

  static void intro()
  {
    System.out.println("     Guess the Number!     ");
    System.out.println("===========================");
    System.out.println("In this game, a random \n" + 
                       "number between 1 and 100 \n" +
                       "will be chosen. You have to \n" +
                       "guess what it is in 4 tries.\n");
  }

  static double hmmoney()
  {
    double money;
    System.out.print("How much money would you like to start with?\nI would like" +
                     " to start with... ");
    money = in.nextDouble();
    System.out.println("");

    return money;
  }

  static double round(double money)
  {
    int guess, actual, guessnum = 1;
    double bet = bet(money);
    boolean correct;

    actual = genint();

    for (;;)
    {
      guess = guess();
      correct = check(guess, actual);
      if (correct == false) {
        guessnum++;
        if (guessnum > 4) {
          System.out.println("You have made the max number of guesses " +
                             "and have lost this round.");
          System.out.println("The correct number was... " + actual + "\n");
          money -= bet;
          break;
        }
        else {
          hint(guess, actual);
        }
      }
      else {
        money += bet;
        break;
      }
    }

    return money;
  }

  static double bet(double money)
  {
    double bet;

    System.out.print("How much money would you like to bet? ");
    bet = in.nextDouble();
    System.out.println("");

    if (bet > money) {
      System.out.println("You can't bet more than you have!");
      bet = bet(money);
    }

    return bet;
  }

  static int genint()
  {
    Random gen = new Random();
    int actual;
    actual = gen.nextInt(100) + 1;

    return actual;
  }

  static int guess()
  {
    int guess;
    System.out.print("I think that the number is... ");
    guess = in.nextInt();
    System.out.println("");

    return guess;
  }

  static boolean check(int guess, int actual)
  {
    if (guess != actual) {
      System.out.println("That is incorrect.");
      return false;
    }
    else {
      System.out.println("Congratulations! You guessed the correct number!");
      return true;
    }
  }

  static boolean check(double money)
  {
    String scont, yes = "yes", no = "no";
    boolean bcont;
    if (money == 0) {
      System.out.println("You are broke and can no longer play.");
      bcont = false;
      return bcont;
    }
    System.out.println("You have " + form.format(money) + " left.");
    System.out.println("Would you like to continue playing? (Yes or no?)");
    scont = System.in.readline();
    if (scont.equalsIgnoreCase(yes)) {
      bcont = true;
      return bcont;
    }
    else if (scont.equalsIgnoreCase(no)) {
      bcont = false;
      return bcont;
    }
    else {
      System.out.println("Invalid answer.");
      bcont = check(money);
      return bcont;
    }
  }

  static void hint(int guess, int actual)
  {
    if (guess > actual) {
      System.out.println("Guess lower!");
    }
    else {
      System.out.println("Guess higher!");
    }
  }

  static String rounds(int roundnum)
  {
    String result;
    if (roundnum == 1) {
      result = "1 Round";
      return result;
    }
    else {
      result = Integer.toString(roundnum) + " Rounds";
      return result;
    }
  }
}

By the way, this is for my AP Java class, that's why the program is what it is. In that function, it will bypass the user input and go right to the else statement after it. Then, it will call itself and will take user input after that.

Patriot524
  • 201
  • 1
  • 3
  • 7
  • What exactly is your problem? Is this method supposed to be a recursive method? – Paul Samsotha Oct 21 '13 at 02:01
  • What's the value for money after this statement **money = round(money);**? also print the value of scont after this line **scont = in.nextLine();**. – Ajeesh Oct 21 '13 at 02:05
  • What @peeskillet asked. Are you saying it ignores whether the user says yes or no to continue? Your own logic specifies that if the user does not say yes or no it does exactly what you are describing. Skips to the else and calls itself. – Radiodef Oct 21 '13 at 02:09
  • @Radiodef I think what the OP is seeing is that it goes through the if/else block and calls itself before the user has a chance to input yes/no. – Dennis Meng Oct 21 '13 at 02:10

3 Answers3

0

So, in this part of the code:

do{
  System.out.println("\nRound " + roundnum + ":");
  System.out.println("-------\n");
  money = round(money);
  cont = check(money);
}while(cont == true);

round() and check() are both functions which use the Scanner object that is declared as a field in your class. round() uses nextInt(), while check() uses nextLine().

What's happening is that when round() is parsing out the guesses, nextInt() doesn't parse out any trailing whitespace after the number input (like a newline from pressing Enter). So, when you call check(), there's still a line for it to read in, and so when you hit this line

scont = in.nextLine();

it reads in that line instead, and since it's obviously not equal to "yes" or "no", it goes to the else block, where it then calls itself.

Since this is for class, I won't actually say how to fix this.

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
  • I won't say thanks yet but your answer seems very logical. I will try to fix it. I just find it interesting that my teacher has never mentioned such a problem like this that may occur. This is also the first time I've encountered such a problem. – Patriot524 Oct 21 '13 at 02:27
  • As a side note, Cem *is* right in saying that a recursive call isn't the way to go, but you can worry about that later. – Dennis Meng Oct 21 '13 at 02:29
  • Wow thank you very much! After `money = round(money)` in the main function, I simply placed `in.nextLine();`. It was the perfect fix. I will have to bring up this complication to my teacher. I had brought this code up in a different post asking about a different problem in the same function and I think someone tried to mention the same problem you just explained to me. However, they did not make sense. Your explanation was very clear. Thanks much again! =D – Patriot524 Oct 21 '13 at 02:36
  • About the recursive call in that function, I guess it is not the right way to go. However I had never found a use to use recursive functions before until now. I have used the method of using a do...while loop to check for valid data and input many times before. I had a realization that I could make it call itself in the case of an error while making this program. – Patriot524 Oct 21 '13 at 02:38
  • `do...while` is the correct way to go. The short explanation is because if you make recursive calls, you need extra memory for each recursive call, and so it's possible to make your program run out of memory by providing improper input over and over. Using `do...while` does not by itself require more memory every iteration, so a user can give improper input all he wants; your program won't run out of memory. – Dennis Meng Oct 21 '13 at 02:42
  • I had thought about that (not lying) while writing that. However, I didn't really think memory would be an issue. But yes, very correct. Would you mind providing an example of when I would use recursive functions? – Patriot524 Oct 21 '13 at 02:47
  • As a general guideline, don't write it recursively if you can't guarantee a limit on the recursion depth that will occur. In this particular case, you can't make that guarantee (because of a potential malicious user). – Dennis Meng Oct 21 '13 at 02:49
0

You can not have in the else section:

  System.out.println("Invalid answer.");
  bcont = check(money);
  return bcont;

...because you are unnecessarily making a recursive call, which I am sure that's not what you want.

Hence, do something like this instead:

scont = System.in.readline();

do {
    scont = System.in.readline();
       if (scont.equalsIgnoreCase(yes)) {
         bcont = true;
         return bcont;

       } else if (scont.equalsIgnoreCase(no)) {
        bcont = false;
        return bcont;

      } else {

       System.out.println("Invalid answer.  Please try again.  Would you like to continue playing? (Yes or no?)");
       scont = System.in.readline();

} while (!scont.equalsIgnoreCase(yes) && !scont.equalsIgnoreCase(yes));
Cem Sultan
  • 354
  • 2
  • 12
0

I recently had a similar problem working with the Scanner, and as Dennis explained, I'm pretty sure it has something to do with previous uses of the Scanner in the execution. Here is a link the question I posted about it.

Try/Catch inside While in static main method

Take a look at some of the answers given there. There's one in particular which visually explains how the Scanner does it's thing which I learned a lot from.

Community
  • 1
  • 1
Justin
  • 164
  • 1
  • 14